斯卡拉 "reflective toolbox failed due to unresolved free type"
Scala "reflective toolbox failed due to unresolved free type"
第一次尝试使用准引号来生成新的案例类:
val universe: scala.reflect.runtime.universe.type = scala.reflect.runtime.universe
import universe._
import scala.reflect.runtime.{currentMirror => m}
import scala.tools.reflect.ToolBox
val toolbox = m.mkToolBox()
trait Father
class A extends Father {
println("I'm A")
val a = 0
}
class B extends Father {
println("I'm B")
val b = 0
}
object Produce {
def A(): A = {
val weakT = weakTypeOf[A]
val genTree = q"""
case class Son() extends $weakT {
println("I'm alive")
}
Son()
"""
val compiledCode = toolbox.eval(genTree)
compiledCode.asInstanceOf[A]
}
def apply[T <: Father](): T = {
val weakT = weakTypeOf[T]
val genTree = q"""
case class Son() extends $weakT {
println("I'm alive")
}
Son()
"""
val compiledCode = toolbox.eval(genTree)
compiledCode.asInstanceOf[T]
}
}
Produce.A()
Produce[A]()
Produce.A() 的结果:
I'm A
I'm alive
res0: A = Son()
Produce[A]() 的结果:
scala.tools.reflect.ToolBoxError: reflective toolbox failed due to unresolved free type variables:
T defined by apply in :32:13
have you forgotten to use TypeTag annotations for type parameters external to a reifee?
if you have troubles tracking free type variables, consider using -Xlog-free-types
at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.verify(ToolBoxFactory.scala:82)
at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.compile(ToolBoxFactory.scala:208)
at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$$anonfun$compile.apply(ToolBoxFactory.scala:429)
at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$$anonfun$compile.apply(ToolBoxFactory.scala:422)
at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$withCompilerApi$.liftedTree2(ToolBoxFactory.scala:355)
at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$withCompilerApi$.apply(ToolBoxFactory.scala:355)
at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl.compile(ToolBoxFactory.scala:422)
at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl.eval(ToolBoxFactory.scala:444)
at Produce$.apply(:40)
... 34 elided
根据@Andreas Jim-Hartmann 的建议,添加了“: TypeTag”(请参阅下面的评论),现在此代码适用于通用和特定:
val universe: scala.reflect.runtime.universe.type = scala.reflect.runtime.universe
import universe._
import scala.reflect.runtime.{currentMirror => m}
import scala.tools.reflect.ToolBox
val toolbox = m.mkToolBox()
trait Father
class A extends Father {
println("I'm A")
val a = 0
}
class B extends Father {
println("I'm B")
val b = 0
}
object Produce {
def A(): A = {
val weakT = weakTypeOf[A]
val genTree = q"""
case class Son() extends $weakT {
println("I'm alive")
}
Son()
"""
val compiledCode = toolbox.eval(genTree)
compiledCode.asInstanceOf[A]
}
def apply[T <: Father : TypeTag](): T = { //Fixed here
val weakT = weakTypeOf[T]
val genTree = q"""
case class Son() extends $weakT {
println("I'm alive")
}
Son()
"""
val compiledCode = toolbox.eval(genTree)
compiledCode.asInstanceOf[T]
}
}
Produce.A()
Produce[A]()
Produce[B]()
第一次尝试使用准引号来生成新的案例类:
val universe: scala.reflect.runtime.universe.type = scala.reflect.runtime.universe
import universe._
import scala.reflect.runtime.{currentMirror => m}
import scala.tools.reflect.ToolBox
val toolbox = m.mkToolBox()
trait Father
class A extends Father {
println("I'm A")
val a = 0
}
class B extends Father {
println("I'm B")
val b = 0
}
object Produce {
def A(): A = {
val weakT = weakTypeOf[A]
val genTree = q"""
case class Son() extends $weakT {
println("I'm alive")
}
Son()
"""
val compiledCode = toolbox.eval(genTree)
compiledCode.asInstanceOf[A]
}
def apply[T <: Father](): T = {
val weakT = weakTypeOf[T]
val genTree = q"""
case class Son() extends $weakT {
println("I'm alive")
}
Son()
"""
val compiledCode = toolbox.eval(genTree)
compiledCode.asInstanceOf[T]
}
}
Produce.A()
Produce[A]()
Produce.A() 的结果:
I'm A
I'm alive
res0: A = Son()
Produce[A]() 的结果:
scala.tools.reflect.ToolBoxError: reflective toolbox failed due to unresolved free type variables: T defined by apply in :32:13 have you forgotten to use TypeTag annotations for type parameters external to a reifee? if you have troubles tracking free type variables, consider using -Xlog-free-types at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.verify(ToolBoxFactory.scala:82) at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.compile(ToolBoxFactory.scala:208) at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$$anonfun$compile.apply(ToolBoxFactory.scala:429) at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$$anonfun$compile.apply(ToolBoxFactory.scala:422) at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$withCompilerApi$.liftedTree2(ToolBoxFactory.scala:355) at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$withCompilerApi$.apply(ToolBoxFactory.scala:355) at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl.compile(ToolBoxFactory.scala:422) at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl.eval(ToolBoxFactory.scala:444) at Produce$.apply(:40) ... 34 elided
根据@Andreas Jim-Hartmann 的建议,添加了“: TypeTag”(请参阅下面的评论),现在此代码适用于通用和特定:
val universe: scala.reflect.runtime.universe.type = scala.reflect.runtime.universe
import universe._
import scala.reflect.runtime.{currentMirror => m}
import scala.tools.reflect.ToolBox
val toolbox = m.mkToolBox()
trait Father
class A extends Father {
println("I'm A")
val a = 0
}
class B extends Father {
println("I'm B")
val b = 0
}
object Produce {
def A(): A = {
val weakT = weakTypeOf[A]
val genTree = q"""
case class Son() extends $weakT {
println("I'm alive")
}
Son()
"""
val compiledCode = toolbox.eval(genTree)
compiledCode.asInstanceOf[A]
}
def apply[T <: Father : TypeTag](): T = { //Fixed here
val weakT = weakTypeOf[T]
val genTree = q"""
case class Son() extends $weakT {
println("I'm alive")
}
Son()
"""
val compiledCode = toolbox.eval(genTree)
compiledCode.asInstanceOf[T]
}
}
Produce.A()
Produce[A]()
Produce[B]()