【问题标题】:Scala Data TypeScala 数据类型
【发布时间】:2014-09-19 21:30:17
【问题描述】:

作为尝试了解 scala 的异同的一部分,我试图了解 Java“Object”类型的等价物。

如果我有一个 Scala 列表 List[TYPE],那么 Type 必须是什么才能支持以下任何一项 整数,任意,(整数,任意))。

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

我最初认为 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 是一切的超类型,为什么要在这里提到不变量?

【问题讨论】:

标签: scala typing


【解决方案1】:

你说得对,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 中的类型参数应该是协变的。 Scala 中的协方差用+ 注释(例如class RDD[+T])。

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

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

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

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

【讨论】:

    【解决方案2】:

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

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

    List[Any] 是正确的类型

    【讨论】:

      猜你喜欢
      • 2023-04-07
      • 2020-03-01
      • 1970-01-01
      • 2021-08-31
      • 2020-09-23
      • 2011-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多