这个scala表达式意味着什么? val h3:持有人[人] = h2

时间:2017-07-27 12:55:43

标签: scala

我一直在关注一些在线教程以学习Scala。我遇到了以下代码段:

class Holder[+T](val value: T) {
  def printIt = println(value)
}

val h1 = new Holder(3)
h1.printIt

class Person
class Employee extends Person

val h2 = new Holder(new Employee)
val h3 : Holder[Person] = h2

不幸的是,老师没有解释val h3表达式对:冒号的影响。有人可以开导我吗?

3 个答案:

答案 0 :(得分:2)

这是一个类型Annotation,Scala可以自动找出变量的类型(称为类型推断),这就是刚刚使用val h3时会发生的情况。但是如果需要,您可以明确指定类型。所以val h3: Holder[Person]表示值h3的类型为Holder[Person]

出于几个原因,您可能希望这样做。第一个是文档。如果指定类型,则清除变量或方法的类型,因此您无需考虑它。如果您不小心犯了错误并尝试将错误的类型放入变量中,它也会导致错误。通常,像本地和私有成员这样的东西没有必要用类型注释来混淆代码,但是将它们包含在任何公共字段或方法中是个好主意。

另一个原因是因为你想要一种不同于推理所确定的类型是合适的。通常(如示例中的情况),这是因为您要分配的实际对象是您希望方法或变量所需类型的子类型。在示例中,h2的类型为Holder[Employee],因此Scala也会为h3推断出类型,但我们希望h3的类型为超类型,{ {1}}所以我们明确地包含了类型注释。

答案 1 :(得分:1)

val h3 : Holder[Person] = h2

上面定义了一个名为h3的值,并为其指定了h2个实例。 :明确指出值h3的类型为Holder[Person]。如果遗漏: Holder[Person]部分,编译器会将h3的类型推断为Holder[Employee](因为h2Holder[Employee])。

h3可以正确地称为Holder[Person]Holder[Employee]。这是因为Holder具有协变类型参数(+T),这意味着由于EmployeePerson的子类型,Holder[Employee]Holder[Person]的子类型1}}。

答案 2 :(得分:0)

+ T声明Holder是协变的,因此Holder [Person]类型的持有者是Holder [Employee]类型持有者的超类。在该行中,您只需声明h3的类型是Holder [Person]。由于协方差,您可以将持有人[员工]分配给持有人[人员]。