我做了一个快速实验,以了解scala的路径相关类型特征的性质:
trait SS {
type II
}
class SS1() extends SS {}
def sameType[T1, T2](implicit ev: T1 =:= T2): Unit = {}
// experiments start here
val a = new SS1()
val b = new SS1()
val c = a
sameType[a.II, a.II]
assertDoesNotCompile(
"""
|sameType[a.II, b.II]
|""".stripMargin
) // of course it happens
到目前为止好吗?直到我输入下一行:
sameType[a.II, c.II]
此时编译器出现以下错误:
[Error] .../PathDependentType/ProveSameType.scala:32: Cannot prove that a.II =:= c.II.
one error found
尽管常数a和c始终引用2个完全相同的对象。那么为什么Scala编译器选择不证明呢?这是否意味着a&c指2个不同的“路径”,并且这种行为在实用性上是预期的?
这是绝对正确的行为。 a
和c
的参考相等性无关紧要。依赖于路径的类型a.II
和c.II
不同。
类型a.II
,c.II
和单例类型are shorthands,a.type#II
的[c.type#II
,a.type
c.type
也不同。
路径https://scala-lang.org/files/archive/spec/2.11/03-types.html#paths
类型等效https://scala-lang.org/files/archive/spec/2.11/03-types.html#equivalence