相同类型归属在变量声明上丢失类型成员信息,但在方法参数声明上不丢失

问题描述

考虑路径依赖类型

trait Foo[In] {
  type Out
  def f(v: In): Out
}

implicit val preciseFooInt: Foo[Int] { type Out = String } = new Foo[Int] {
  type Out = String
  def f(v: Int): String = v.toString
}

我们看到输出类型 Out 声明为类型成员。还要注意 preciseFooInt 实例的精确声明类型

Foo[Int] { type Out = String }

现在让我们通过强制赋值给它的超类型来失去类型成员的精度

val ev: Foo[Int] = preciseFooInt

因为我们省略了类型细化 { type Out = String },编译器不知道输出类型正是 String,这很有意义

scala> val ev: Foo[Int] = preciseFooInt
val ev: Foo[Int] = $anon$1@2fd641f6

scala> val s: String = ev.f(42)
                           ^
       error: type mismatch;
        found   : ev.Out
        required: String

但是让我们做非常相似的动作,但是通过方法参数声明

def g(ev: Foo[Int]) = ev.f(42)

注意方法参数 ev 如何与之前的变量 ev 具有完全相同的类型归属,即 Foo[Int] 没有特定类型成员细化 { type Out = String }。尽管如此,现在类型成员精度没有损失

scala> def g(ev: Foo[Int]) = ev.f(42)
def g(ev: Foo[Int]): ev.Out

scala> val s: String = g(ev = preciseFooInt)
val s: String = 42

关于类型成员的变量声明和方法参数声明有什么区别?鉴于两种情况下的类型归属相同,为什么方法参数情况下没有信息丢失?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)