2012-09-17 24 views
7

का उपयोग करके प्रकार तर्कों का रनटाइम रिज़ॉल्यूशन एक प्रकार की घोषणा को देखते हुए, मैं प्रकार तर्क को हल करने में सक्षम हूं।स्कैला 2.10 प्रतिबिंब

scala> reflect.runtime.universe.typeOf[List[Int]] match {case x:TypeRef => x.args} 
res10: List[reflect.runtime.universe.Type] = List(Int) 

रनटाइम मान के लिए, वही विधि काम नहीं करती है।

scala> reflect.runtime.currentMirror.reflect(List(42)).symbol.toType match {case x:TypeRef => x.args} 
res11: List[reflect.runtime.universe.Type] = List(B) 

क्या प्रतिबिंबित मूल्यों के लिए प्रकार के क्षरण को दूर करने का कोई तरीका है?

+0

शायद आप [इस उत्तर] को पढ़ने के बाद एक व्यावहारिक समाधान पा सकते हैं (http://stackoverflow.com/a/1094214/315306) – Raffaele

+0

@Raffaele। संदर्भ के लिए धन्यवाद। दुर्भाग्यवश प्रश्न (और उत्तर) मामले के साथ सौदा करते हैं जब प्रकार ठोस होते हैं और संकलन समय के दौरान ज्ञात होते हैं। प्रकटताओं को अब हटा दिया गया है, और टाइपटैग (जो प्रकट होते हैं) कंक्रीट टैग की आवश्यकता होती है। –

+1

AbsTypeTag का उपयोग करें (आरसी 1 में नाम बदलकर वीकटाइपटैग)। यहां अधिक जानकारी: http://stackoverflow.com/questions/12218641/scala-2-10-what-is-a-typetag-and-how-do-i-use-it –

उत्तर

6

एक उदाहरण TypeTag ज्ञान के आधार पर Scala: What is a TypeTag and how do I use it? पोस्ट पढ़ने से प्राप्त Eugene Burmako आपके प्रश्न पर टिप्पणी में से:

$ scala ScalaApplication.scala 
List[Int] 
List[String] 
List[Any] 

[अद्यतन:

import scala.reflect.runtime.universe._ 

object ScalaApplication { 
    def main(args: Array[String]) { 
    printType(List(42)) 
    printType(List("42")) 
    printType(List("42", 42)) 
    }  

    def printType[T : TypeTag](t: T) { 
    println(typeOf[T]) 
    } 
} 

यह आउटपुट देना चाहिए 1:]

हालांकि, अगर आप आप प्रकार के बारे में पता आवरण के कुछ प्रकार के लिए चुनते हैं हो सकता है Any प्रकार प्रकार का एक संदर्भ करने के लिए आवंटित के बारे में पता होना चाहते हैं:

$ scala ScalaApplication.scala 
42 has type Int 
a string has type String 
true has type Boolean 
:

import scala.reflect.runtime.universe._ 

object ScalaApplication { 
    def main(args: Array[String]) { 
    val anyWrapper = new AnyWrapper 

    List(1,2,3).foreach { i => 
     i match { 
     case 1 => anyWrapper.any = 42 
     case 2 => anyWrapper.any = "a string" 
     case 3 => anyWrapper.any = true 
     } 
     print(anyWrapper.any) 
     print(" has type ") 
     println(anyWrapper.typeOfAny) 
    } 
    } 

    class AnyWrapper { 
    private var _any: Any = null 
    private var _typeOfAny: Type = null 

    def any = _any 
    def typeOfAny = _typeOfAny 
    def any_=[T: TypeTag](a: T) = { 
     _typeOfAny = typeOf[T] 
     _any = a 
    } 

    } 
} 

यह आउटपुट देना चाहिए

लेकिन यह समाधान अभी भी उस मामले को कवर नहीं करता है जहां संदर्भ प्रकार संकलन समय पर अज्ञात है।

[अद्यतन 2:]

प्रकार स्पष्ट प्रकार Any के संदर्भ के लिए डाली रहे हैं, तो आप प्रकार की वसूली के लिए एक मैच बयान में हर संभव प्रकार की गणना करने में हो सकता है:

import scala.reflect.runtime.universe._ 

object ScalaApplication { 
    def main(args: Array[String]) { 

    List(1,2,3).foreach { i => 
     val any: Any = i match { 
     case 1 => 42.asInstanceOf[Any] 
     case 2 => "a string".asInstanceOf[Any] 
     case 3 => true.asInstanceOf[Any] 
     } 
     print(any) 
     print(" has type ") 
     println(matchType(any)) 
    } 
    } 

    def matchType(any: Any) = { 
    any match { 
     case a: Int => typeOf[Int] 
     case a: String => typeOf[String] 
     case a: Boolean => typeOf[Boolean] 
    } 
    } 
} 

यह आउटपुट देना चाहिए:

$ scala ScalaApplication.scala 
42 has type Int 
a string has type String 
true has type Boolean 

लेकिन इस समाधान आप को पता है की आवश्यकता है (एक एनडी सूची) any मूल्य में प्राप्त होने वाले सभी संभावित प्रकार।

+0

यह समाधान केवल तभी काम करता है जब प्रकार है संकलन समय में जाना जाता है। स्केला> वैल एक्स:: किसी भी = सूची (42) एक्स: किसी भी = सूची (42) स्केला> प्रिंट प्रकार (एक्स यहाँ एक वस्तु, जिसका मान संकलन समय में नहीं जाना जाता है पर प्रिंट प्रकार का एक परिणाम है) कोई भी –

+0

आपके मूल प्रश्न से मैंने सोचा था कि आप विशेष रूप से 'सूची (42)' जैसी चीज़ों के लिए रनटाइम पर टाइप पैरामीटर प्राप्त करने में सक्षम होना चाहते हैं, जहां टाइप तर्क केवल स्पष्ट रूप से नहीं दिए गए हैं। –

+0

मैंने अपना उत्तर एक रैपर के उदाहरण के साथ अपडेट किया है जो आपको आवश्यकतानुसार हो सकता है। क्या ऐसा रैपर आपकी समस्या का समाधान करेगा? –