为什么创建元组的显式语法只允许使用AnyRefs作为类型注释?

3
这段代码是可行的:
scala> val x = ""
x: java.lang.String = ""

scala> Tuple2[x.type, x.type](x,x)
res5: (x.type, x.type) = ("","")

这个不行:
scala> val y = 0
y: Int = 0

scala> Tuple2[y.type, y.type](y,y)
<console>:9: error: type mismatch;
 found   : y.type (with underlying type Int)
 required: AnyRef
Note: an implicit exists from scala.Int => java.lang.Integer, but
methods inherited from Object are rendered ambiguous.  This is to avoid
a blanket implicit which would convert any scala.Int to any AnyRef.
You may wish to use a type ascription: `x: java.lang.Integer`.
              Tuple2[y.type, y.type](y,y)
                     ^

除此之外,还有这个:

scala> val z = ()
z: Unit = ()

scala> Tuple2[z.type, z.type](z,z)
<console>:9: error: type mismatch;
 found   : z.type (with underlying type Unit)
 required: AnyRef
Note: Unit is not implicitly converted to AnyRef.  You can safely
pattern match `x: AnyRef` or cast `x.asInstanceOf[AnyRef]` to do so.
              Tuple2[z.type, z.type](z,z)
                     ^

语言规范说明:

单例类型的形式为 p.type,其中 p 是指向预期符合 scala.AnyRef (§6.1)的值的路径。

这个限制的背后有什么理由?最近类似于 0.getClass 的限制是否有意义?

正如您的示例所示,它与元组毫无关系。关键是您无法在值类型上执行.type操作。我不知道这是否可行,并想知道何时可能有用。 - Didier Dupont
这不就是我引用的内容吗(§6.1),我想知道背后的原理是什么? - soc
确实,你的问题就是这样结束了。但是标题(以及你的示例)提到了元组。 - Didier Dupont
由于 JVM 上存在类型擦除,我不建议使用 ".type"。如果您想在类型上灵活,请使用泛型。 - Arne
1个回答

0

正如您在Scala类层次结构中所看到的,IntUnitBoolean(以及其他类型)不是AnyRef的子类,因为它们被转换成Java的intvoidboolean等类型,这些类型不是Object的子类。


但是为什么会有这个限制存在呢? - soc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接