reflection - 路径相关类型与 "underlying types",检查哪些类型?

标签 reflection scala type-systems path-dependent-type abstract-type

当使用带有反射的路径相关类型时,即使我有匹配的“底层类型”,我也会收到类型不匹配错误。这些“非底层类型”是什么?为什么检查它们而不是“底层类型”?

在下面的代码中,我希望 compare 方法仅接受 A 的相同类型子类作为参数。错误出现在最后一行。

abstract class A(val a:Int) {
  type Impl <: A
  def compare(other:Impl) {
    if(a==other.a) println("equal") else println("diff")
  }
}
class B(a:Int) extends A(a) {type Impl = B}

object Test {
  def newInst(a: Int, className: String) = {
    val constr = Class.forName(className).getConstructors()(0)
    constr.newInstance(a.asInstanceOf[AnyRef]).asInstanceOf[A]
  }

  def main(args: Array[String]) {
    val b1 = newInst(4, "B")
    val b2 = newInst(5, "B")
    b1.compare(b2)   // type mismatch error here
  }
}

在最后一行我收到此错误:

error: type mismatch;
found   : b2.type (with underlying type A)
required: b1.Impl

由于 b2 的类型与 b1 的类型(即 A)相同,因此我预计这不会生成错误。由于某种原因,这些路径相关类型与使用反射时的“底层类型”不同。为什么?

如果我不使用反射,它会起作用:

val b1 = new B(4)
val b2 = new B(5)
b1.compare(b2)  // no errors

(在我的例子中我确实需要使用反射)。 newInst() 可以使用反射将对象作为类“B”返回吗?这有帮助吗?使用抽象类型时是否存在类型删除?

这是我发现的关于相同错误的唯一引用 ( on this forum ),但可能不相关。

最佳答案

这与反射没有任何关系。 b1b2 的类型是 A(因为这是 newInst 的返回类型)。要编译调用 b1.compare(b2)b2 必须具有类型 b1.Impl。编译器只知道它是 A 的某种子类型,但不知道是哪一个。由于您无法传递需要 A 某些子类型的 A,因此您会收到错误。

在示例中

val b1 = new B(4)
val b2 = new B(5)
b1.compare(b2)  // no errors

两个变量的类型均为 B,并且 B#ImplB,因此所有内容都会进行类型检查。

关于reflection - 路径相关类型与 "underlying types",检查哪些类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4880529/

相关文章:

scala - 使用 scala Type 设置类型参数(通过 TypeTag?)

c# - 需要建议 : alternative to overloading "is" and "as" operators in . NET

haskell - 我如何解释这篇论文上的打字规则?

reflection - 解决反射开销的最佳方法是什么?

c# - 如何在封闭泛型类型上获取泛型方法,从开放泛型类型打开 MethodInfo?

java - 从类名中获取 Gson TypeToken 作为字符串

java - 我可以使用什么库在 Java 或 Scala 中计算大型稀疏矩阵?

scala - 将案例类转换为另一个递归结构相同的案例类

scala - 用于与 Scala 解析器组合器匹配的自定义逻辑

dynamic-typing - Matlab:为什么是 '1' + 1 == 50?