为什么scala不会将这种类型的lambda与底层类型统一起来?

JbG*_*bGi 6 scala existential-type

trait A {
  type T
  def test(t: T): Unit
}

case class B[S <: A](a: S, t : S#T) {
  def test() = a.test(t) // Error: type mismatch;
    // found   : B.this.t.type (with underlying type S#T)
    // required: B.this.a.T
}
Run Code Online (Sandbox Code Playgroud)

我错误地期望上面的编译?我的代码可以修复吗?

Odo*_*ois 8

编译器没有足够的证据S#T可以test在具体实例中用作参数.

考虑弱化scala编译器的这个低级示例

trait A2 extends A{
  type T <: AnyRef
}

class A3 extends A2{
  override type T = Integer

  def test(t: Integer): Unit = println(t * 2)
}
Run Code Online (Sandbox Code Playgroud)

所以B[A2]应该接受的情况下A3不惜一切是<: AnyRef同时A3需要准确地Integer为自己test实施

您可以在定义中捕获具体类型B,以确保将使用哪种类型

case class B[S <: A, ST](a: S {type T = ST}, t: ST) {
  def test() = a.test(t) 
}
Run Code Online (Sandbox Code Playgroud)

  • 但是`B [A2](新的A3(),"")`虽然不编译......你的意思是它会用我的代码吗?否则,您的解决方案正是我所需要的. (2认同)