स्कैला में रनटाइम पर क्लास पैरामीटर डेटाटाइप को कैसे खोजें
import scala.reflect.runtime.universe
import scala.reflect.runtime.universe._
def getType[T: TypeTag](obj: T) = typeOf[T]
case class Thing(
val id: Int,
var name: String
)
val thing = Thing(1, "Apple")
val dataType = getType(thing).decl(TermName("id")).asTerm.typeSignature
dataType match {
case t if t =:= typeOf[Int] => println("I am Int")
case t if t =:= typeOf[String] => println("String, Do some stuff")
case _ => println("Absurd")
}
पचने में सक्षम नहीं है Absurd
इसके बजाय परिणाम क्यों है I am int
?
मेरा उद्देश्य रनटाइम के डेटा-प्रकार के क्लास पैरामीटर को जानना और पूर्वनिर्धारित प्रकारों से मिलान करना है।
जवाब
दोनों वर्तमान dataType
और typeOf[Int]
के रूप में मुद्रित कर रहे हैं Int
लेकिन यदि आप ऐसा showRaw
आप क्यों वे मेल नहीं खाते देखेंगे
showRaw(dataType) // NullaryMethodType(TypeRef(ThisType(scala), scala.Int, List()))
showRaw(typeOf[Int]) // TypeRef(ThisType(scala), scala.Int, List())
बात यह है कि बस प्रकार Int
और अशक्त विधि वापसी के Int
विभिन्न प्रकार हैं।
जोड़ने की कोशिश करें .resultType
val dataType = getType(thing).decl(TermName("id")).asTerm.typeSignature.resultType
dataType match {
case t if t =:= typeOf[Int] => println("I am Int")
case t if t =:= typeOf[String] => println("String, Do some stuff")
case _ => println("Absurd")
} // I am Int
यह भी ध्यान देने योग्य है कि .decl(TermName("id"))
रिटर्न गेटर सिंबल, यह .decl(TermName("id "))
(रिक्त स्थान के साथ) है जो फील्ड सिम्बल लौटाता है। तो वैकल्पिक रूप से आप प्रतीक नाम और बिना खाली जगह के साथ कर सकते हैं.resultType
val dataType = getType(thing).decl(TermName("id ")).asTerm.typeSignature
मैं @TomerShetah के उत्तर में जोड़ता हूँ कि यदि लक्ष्य एक केस क्लास के सभी क्षेत्रों में "पैटर्न मैचिंग" है तो यह शेपलेस के साथ संकलन समय (अधिकतर) में भी किया जा सकता है :
import shapeless.Poly1
import shapeless.syntax.std.product._
object printTypes extends Poly1 {
implicit val int: Case.Aux[Int, Unit] = at(t => println(s"I am Int: $t")) implicit val string: Case.Aux[String, Unit] = at(t => println(s"String, Do some stuff: $t"))
implicit def default[V]: Case.Aux[V, Unit] = at(t => println(s"Absurd: $t"))
}
thing.toHList.map(printTypes)
// I am Int: 1
// String, Do some stuff: Apple
https://scastie.scala-lang.org/DmytroMitin/N4Idk4KcRumQJZE2CHC0yQ
@Dmytrio जवाब एक महान स्पष्टीकरण है कि प्रतिबिंब ने आपकी अपेक्षा के अनुरूप काम क्यों नहीं किया।
मैं आपके प्रश्न से समझ सकता हूं, कि आप जो करने की कोशिश कर रहे हैं, वह वास्तव में एक केस क्लास में आपके सभी वेरिएबल्स से मेल खाता है। कृपया इसे निम्नलिखित तरीके से करने पर विचार करें:
case class Thing(id: Int, name: String)
val thing = Thing(1, "Apple")
thing.productIterator.foreach {
case t: Int => println(s"I am Int: $t") case t: String => println(s"String, Do some stuff: $t")
case t => println(s"Absurd: $t")
}
स्कैस्टी में कोड रन ।