使用scala 2.12.10
假设我想在运行时将case类隐式转换为Special
case类SpecialString
。隐式转换由trait提供External
。的名称SpecialString
应为类的声明名称Special
。
import scala.reflect.runtime.universe.{runtimeMirror, typeOf}
import scala.reflect.runtime.universe
case class Special(i: Int)
case class SpecialString(s: String)
trait External {
val rm = runtimeMirror(getClass.getClassLoader)
val im = rm.reflect(this)
val members = im.symbol.typeSignature.members
def specials: Iterable[universe.Symbol] = members.filter(_.typeSignature <:< typeOf[Special] )
implicit def SpecialIntToString(s: Special): SpecialString = {
val name = im.reflectField(specials.filter(x => im.reflectField(x.asTerm).get.asInstanceOf[Special] == s).head.asTerm).symbol.toString.replace("value ", "")
SpecialString(s"name = $name")
}
}
目前,我能够隐式转换在扩展External
特性的类内声明的转换成员。
class MyClass extends External {
val firstSpecial = Special(1)
val two = 2
val specialS: SpecialString = firstSpecial
}
class MySecondClass extends MyClass {
val specialS2: SpecialString = firstSpecial
}
val myClass = new MyClass
print(myClass.specialS) // SpecialString(name = firstSpecial)
但是我无法转换在超类中声明的成员
class MyClass {
val firstSpecial = Special(1)
val two = 2
val specialS: SpecialString = firstSpecial
}
class MySecondClass extends MyClass with External {
val specialS2: SpecialString = firstSpecial
}
val myClass = new MyClass
print(myClass.specialS)
val mySecondClass = new MySecondClass
print(mySecondClass.specialS2) // java.util.NoSuchElementException: next on empty iterator
有什么帮助吗?
如果您按名称而不是typeSignature
(然后实际找到了)找到了必要的成员并进行打印specials.head.typeSignature
,typeOf[Special]
您将看到为什么一个不是另一个的子类型
trait External {
...
def specials: Iterable[universe.Symbol] =
members.filter(_.name == universe.TermName("firstSpecial") )
//members.filter(_.typeSignature.resultType <:< typeOf[Special] )
println(s"specials.head.typeSignature=${specials.head.typeSignature}=${universe.showRaw(specials.head.typeSignature)}")
println(s"typeOf[Special]=${typeOf[Special]}=${universe.showRaw(typeOf[Special])}")
println(s"specials.head.typeSignature <:< typeOf[Special]=${specials.head.typeSignature <:< typeOf[Special]}")
...
}
//specials.head.typeSignature=pckg.App.Special=NullaryMethodType(TypeRef(ThisType(pckg.App), pckg.App.Special, List()))
//typeOf[Special] =pckg.App.Special=TypeRef(ThisType(pckg.App), pckg.App.Special, List())
//specials.head.typeSignature <:< typeOf[Special]=false
返回的无效方法Special
的类型不是的子类型Special
。
您应该添加resultType
。更换
trait External {
...
def specials: Iterable[universe.Symbol] =
members.filter(_.typeSignature <:< typeOf[Special] )
与
trait External {
...
def specials: Iterable[universe.Symbol] =
members.filter(_.typeSignature.resultType <:< typeOf[Special])
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句