【问题标题】:Basic Scala reflection code using recursive types does not compile. Why ? How can it be fixed?使用递归类型的基本 Scala 反射代码无法编译。为什么 ?如何修复?
【发布时间】:2014-03-03 12:47:30
【问题描述】:

以下 Scala 代码,使用 recursive type A 无法编译:

package reflection.scala.stackOverflow

import scala.reflect.runtime.universe._

class A[T<:A[T]]

class Question(root:A[_]) {
  val rtmMirror                   =runtimeMirror(getClass.getClassLoader)
  val instanceMirror : InstanceMirror =rtmMirror.reflect(root)
}

它给出以下编译错误:

Error:(9, 50) type arguments [_$1] do not conform to class A's type parameter bounds [T <: reflection.scala.stackOverflow.A[T]]
  val instanceMirror : InstanceMirror =rtmMirror.reflect(root)
                                                 ^
Error:(9, 57) type arguments [_$1] do not conform to class A's type parameter bounds [T <: reflection.scala.stackOverflow.A[T]]
  val instanceMirror : InstanceMirror =rtmMirror.reflect(root)
                                                        ^
  • 为什么编译失败?

  • 这里的类型参数 $1 是什么?

  • 1 美元从何而来?

  • 为什么 $1 不符合 A 的类型参数界限?

  • 如何修改此代码以便在编译时将root 的类型检查保留为A 的类型?

【问题讨论】:

    标签: scala reflection types recursive-datastructures


    【解决方案1】:

    如果你不告诉它A的参数是正确的类型,它会填写一个匿名类型参数(_$1是用于A的参数的匿名类型)和不一定会使其像需要的那样具体。只需自己指定一个有效类型即可:

    class Question[T <: A[T]](root: A[T])
    

    编译器会很高兴的。

    【讨论】:

      【解决方案2】:

      如果你真的不在乎:

      scala> import scala.reflect.runtime._
      import scala.reflect.runtime._
      
      scala> import universe._
      import universe._
      
      scala> class A[T<:A[T]] { def a: T = null.asInstanceOf[T] }
      defined class A
      
      scala> def f(x: A[_]) = currentMirror reflect[A[_]] x
      f: (x: A[_])reflect.runtime.universe.InstanceMirror
      
      scala> f(new A)
      res0: reflect.runtime.universe.InstanceMirror = instance mirror for A@5b369cb9
      
      scala> typeOf[A[_]].member(TermName("a")).asMethod
      res1: reflect.runtime.universe.MethodSymbol = method a
      
      scala> res0 reflectMethod res1
      res2: reflect.runtime.universe.MethodMirror = method mirror for A.a: T (bound to A@5b369cb9)
      
      scala> res2()
      res3: Any = null
      

      我想要一件正面有X[_] 和背面有I dont care what type you think I am. 的黑色仿旧T 恤,也许措辞更强烈。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-11
        • 1970-01-01
        相关资源
        最近更新 更多