Scala çalışma zamanı yansımaları, iç sınıflar için bile belirli bir türün tüm üyelerini alır
Scala ile 2.12.10
Ben örtük bu durumda, çalışma zamanında bir vaka sınıfını dönüştürmek istediğiniz varsayalım Special
bir olgu sınıfına SpecialString
. Örtük dönüştürme bir özellik tarafından sağlanır External
. Adı SpecialString
, sınıfın bildirim adı olmalıdır 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")
}
}
Şu anda, External
özelliği genişleten bir sınıf içinde bildirilen dönüştürücü üyeleri dolaylı olarak dönüştürebiliyorum .
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)
Ancak süper sınıfta beyan edilen üyeleri dönüştüremiyorum
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
Herhangi bir yardım?
Yanıtlar
Eğer yerine adıyla gerekli üyesini bulursanız typeSignature
(ve aslında o bulduğuna) ve yazdırmak specials.head.typeSignature
ve typeOf[Special]
birbirlerine bir alt tür değil neden göreceksiniz
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
Dönen boş bir yöntemin türü, öğesinin Special
bir alt türü değildir Special
.
Eklemelisiniz resultType
. Değiştir
trait External {
...
def specials: Iterable[universe.Symbol] =
members.filter(_.typeSignature <:< typeOf[Special] )
ile
trait External {
...
def specials: Iterable[universe.Symbol] =
members.filter(_.typeSignature.resultType <:< typeOf[Special])
Scala'da çalışma zamanında sınıf parametresi veri türü nasıl bulunur