Scala数据类型

时间:2014-09-19 21:30:18

标签: scala typing

作为尝试理解scala的差异和相似之处的一部分,我试图理解Java“Object”类型的等价物。

如果我有一个Scala列表List [TYPE],那么Type必须支持以下任何一项 Int,Any,(Int,Any))。

注意:我理解这是一种糟糕的(可怕的)编程技术,但它有助于我理解。

我最初认为List [Any]会起作用,但无法让它适用于所有情况:

[error]  found   : org.apache.spark.rdd.RDD[Any]
[error]  required: org.apache.spark.rdd.RDD[(Any, ?)]

类似地

[error]  found   : org.apache.spark.rdd.RDD[(Any, (Any, Any))] [error] required: org.apache.spark.rdd.RDD[Any] [error] Note: (Any, (Any, Any)) <: Any, but class RDD is invariant in type T.

如果Any是一种超级类型的东西,为什么在这里提到不变量?

2 个答案:

答案 0 :(得分:3)

你是Any是Scala中所有类型的超类型。

错误消息是由不同的问题引起的。

[error]  found   : org.apache.spark.rdd.RDD[Any]
[error]  required: org.apache.spark.rdd.RDD[(Any, ?)]

在这种情况下,您具有超类型的混合子类型。该错误表明您已使用Any而不是(Any, ?),只允许使用其他方式。

[error]  found   : org.apache.spark.rdd.RDD[(Any, (Any, Any))] [error] required: org.apache.spark.rdd.RDD[Any] [error] Note: (Any, (Any, Any)) <: Any, but class RDD is invariant in type T.

这里的问题是多态和方差注释。如果类型变量是不变的(既不是协变也不是逆变),则类型必须是完全匹配。您不能使用子类型或超级类型。

协方差

要允许第二个用例,RDD中的type参数应该是协变的。 Scala中的协方差使用+注释(例如class RDD[+T])。

协方差意味着如果类型AB的子类型且Foo在其第一个类型参数中是协变的,则Foo[A]是子类型Foo[B]

Scala <:用于描述类型之间的顺序(子/超类型关系)。

(Any, (Any, Any)) <: Any

表示(Any, (Any, Any))Any的子类型,但RDD不是协变的,因此RDD[(Any, (Any, Any))] <: RDD[Any]是错误的。

答案 1 :(得分:2)

您可以使用scala控制台和类型推断来检查您将拥有的类型:

scala> val list = List(1, (2, "String"), Array.empty[Byte])
list: List[Any] = List(1, (2,String), Array())

列表[任意]是正确的类型