Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala类型参数在不同的地方_Scala_Oop_Types_Functional Programming - Fatal编程技术网

Scala类型参数在不同的地方

Scala类型参数在不同的地方,scala,oop,types,functional-programming,Scala,Oop,Types,Functional Programming,我刚刚开始学习scala,对类型参数的一般理解有一些问题。以前我学过Haskell,但在scala我觉得很困惑。我不清楚应该把类型参数放在哪里(靠近类定义或函数定义) 举个例子: class Person[A] { def sayName (name: A) = println(name) } 将类型参数从类移动到函数有意义吗 class Person { def sayName[A] (name: A) = println(name) } 或者我甚至可以在类和函数中保留类型参数,这

我刚刚开始学习scala,对类型参数的一般理解有一些问题。以前我学过Haskell,但在scala我觉得很困惑。我不清楚应该把类型参数放在哪里(靠近类定义或函数定义)

举个例子:

class Person[A] {
  def sayName (name: A) = println(name)
}
将类型参数从类移动到函数有意义吗

class Person {
  def sayName[A] (name: A) = println(name)
}
或者我甚至可以在类和函数中保留类型参数,这样它就可以工作了。这会有很大的不同吗? 函数中的[A]参数会覆盖类定义中的相同参数吗

我可以创建Person的实例或调用函数,而无需指出确切的类型

val p = new Person();
那么这是为什么?只是万一我想要smth通用的? 因此,我不清楚何时以及在哪些位置(类或函数)应该放置类型参数。

  • 如果在类级别声明类型参数,则在构造时指定实际类型,以后不能更改它-给定实例上的
    sayName
    的所有调用都必须使用相同的类型

  • 如果在方法级别描述类型参数,则可以在方法的每次调用中指定不同的类型

因此,如果类的实例应始终应用于单个类型,请使用类级别定义

例如:

trait Animal
case class Dog() extends Animal
case class Cat() extends Animal

// A single owner has a *specific* pet, 
// so it makes sense to declare type at class level
class Owner[A <: Animal] {
  def feed(a: A) = ???
}

// A single RandomAnimalLover walking down the street, 
// might feed both Dogs and Cats - so their feed method must be parameterized, and there's no use in adding a parameter at the class level
class RandomAnimalLover {
  def feed[A <: Animal](a: A) = ???
}

val dog = Dog()
val cat = Cat()
val ownerA = new Owner[Dog]
val randomDude = new RandomAnimalLover

ownerA.feed(dog) // compiles
ownerA.feed(cat) // does not compile

randomDude.feed(dog) // compiles
randomDude.feed(cat) // compiles
trait动物
case类Dog()扩展了动物
case类Cat()扩展了Animal
//一个单独的主人有一个特定的宠物,
//因此,在类级别声明类型是有意义的

类所有者[A您想要实现的目标将决定将类型参数放置在何处

类定义中的类型参数 将类型参数放入类定义中,使类的某些属性成为泛型。它可以是
val
、类参数或函数参数

方法定义中的类型参数 将类型参数放入类定义中,以允许使用泛型类型调用方法

例子
class-Person[A](姓名:A){
def sayName=println(名称)
def sayFirstName(firstName:A)=println(firstName)
def saySomething[B](thing:B)=println(s“$name表示$thing”)
}
//控制台中
scala>val p=新人[字符串](“巴克”)
p:Person[字符串]=Person@4f5a80a8
scala>p.sayName
巴克
scala>p.sayFirstName(“约翰”)
约翰
scala>p.sayFirstName(4)
:14:错误:类型不匹配;
发现:Int(4)
必需:字符串
p、 sayFirstName(4)
^
scala>p.说点什么(“你好”)
巴克说你好
scala>p.saySomething(42)
巴克说42
方法
sayFirstName
接受与
name
类型相同的参数。我希望
name
firstName
具有相同的类型,我可以通过这种方式强制执行

方法
saySomething
有一个新的类型参数
B
。因此
人可以说任何类型的话

旁注 正如您所指出的,您也可以用
A
替换
B
,并具有相同的行为:方法定义中的类型参数将覆盖类定义中的类型参数。但为了可读性,应该避免这种情况