Scala 各个地方的类型参数

Ser*_*bei 2 oop types functional-programming scala

我刚刚开始学习 Scala 并且对类型参数的一般理解有一些问题。以前我学习了 Haskell,但在 Scala 中它对我来说似乎很混乱。我不清楚应该把类型参数放在哪里(靠近类定义或函数定义)。

考虑这个例子:

class Person[A] {
  def sayName (name: A) = println(name)
}
Run Code Online (Sandbox Code Playgroud)

将类型参数从类移动到函数是否有意义?

class Person {
  def sayName[A] (name: A) = println(name)
}
Run Code Online (Sandbox Code Playgroud)

或者我什至可以在类和函数中保留类型参数,它会起作用。它有什么大的不同吗?函数中的 [A] 参数会覆盖类定义中的相同参数吗?

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

val p = new Person();
Run Code Online (Sandbox Code Playgroud)

那么这是为什么呢?只是在我想要通用的情况下?所以我不清楚我应该在什么时候以及在哪个位置(类或函数)放置类型参数。

Tza*_*har 7

  • 如果在级别声明类型参数,则在构造时分配实际类型,并且以后不能更改它 -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
Run Code Online (Sandbox Code Playgroud)

最后,如果您在类级别和方法级别声明了一个类型参数- 这是两个单独的参数。如果它们有不同的名称 - 两者都可以在任何地方使用;如果它们具有相同的名称,方法级别的参数将影子该方法的定义和执行(但无处可在类)的范围内一流水平的参数。