我做了一个快速实验来理解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
是a.type#II
型、c.type#II
型和单例型a.type
的简写,c.type
也是不同的。
路径 https://scala-lang.org/files/archive/spec/2.13/03-types.html#paths
类型 https://scala-lang.org/files/archive/spec/2.13/03-types.html#equivalence 的等效性