2012-10-11 16 views
21

का उपयोग प्रकार टैग, मैं कर सकती हूं किसी प्रकार की मापदंडों को देखने के लिए:स्कैला 2.10 में प्रतिबिंब के माध्यम से टाइप पैरामीटर ढूँढना?

scala> import scala.reflect.runtime.universe._ 
import scala.reflect.runtime.universe._ 

scala> typeOf[List[Int]] 
res0: reflect.runtime.universe.Type = List[Int] 

लेकिन मैं काफी समझ नहीं प्रोग्राम प्राप्त करने के लिए है कि "इंट" वहाँ से बाहर, एक में सामान्य तरीका

(मैं अब एक घंटे के लिए आरईपीएल में घूम रहा हूं, टाइप पर क्रमपरिवर्तन की कोशिश कर रहा हूं, यह देखने के लिए कि मैं इससे क्या प्राप्त कर सकता हूं ... मुझे बहुत सी चीजें मिलती हैं जो इंगित करती हैं कि यह एक "सूची" है, लेकिन "इंट" ढूंढने पर शुभकामनाएँ! और मैं वास्तव में toString() आउटपुट को पार्स करने का सहारा लेना नहीं चाहता ...)

डैनियल सोब्राल में उत्कृष्ट (सामान्य के रूप में) त्वरित अवलोकन here है, जिसमें वह प्राप्त करता है tantalizingly मैं क्या तलाश कर रहा हूँ, लेकिन के करीब (जाहिरा तौर पर) केवल यदि आप पता करने के लिए होता है, उस विशेष वर्ग के लिए, कुछ विशिष्ट विधि है जिसका प्रकार से पूछताछ की जा सकती है:

scala> res0.member(newTermName("head")) 
res1: reflect.runtime.universe.Symbol = method head 

scala> res1.typeSignatureIn(res0) 
res2: reflect.runtime.universe.Type = => Int 

लेकिन मैं कुछ और सामान्य की उम्मीद कर रहा हूं, जिसमें घोषित विधियों की सूची में चारों ओर घूमना शामिल नहीं है और उम्मीद है कि उनमें से एक टैग की वर्तमान प्रकार की जानकारी कहीं और कैप्चर करेगा (और इस प्रकार बताएगा)।

यदि स्कैला इतनी आसानी से प्रिंट "सूची [Int]" है, तो पृथ्वी पर क्यों "int" भाग खोजना इतना कठिन है - स्ट्रिंग पैटर्न मिलान का उपयोग किए बिना? या क्या मैं वास्तव में कुछ सचमुच याद कर रहा हूं, वास्तव में स्पष्ट?

scala> res0.typeSymbol.asInstanceOf[ClassSymbol].typeParams 
res12: List[reflect.runtime.universe.Symbol] = List(type A) 

scala> res12.head.typeSignatureIn(res0) 
res13: reflect.runtime.universe.Type = 

Grr ...

+0

यहाँ देखें एक गैर जवाब है: के साथ M7 कम से कम आप एक आंतरिक कास्ट कर प्रकार तर्क प्राप्त कर सकते हैं एपीआई: 'टाइपऑफ [सूची [Int]]। AsInstanceOf [scala.reflect.internal.Types $ TypeApiImpl] .typeArguments'। –

+0

चालाक! धन्यवाद। – Tim

उत्तर

14

दुःख की बात है मुझे नहीं लगता कि एक विधि है कि आप मापदंडों दे देंगे बनाया जा सकता है, लेकिन आप उन्हें पकड़ इस तरह से प्राप्त कर सकते हैं:

Welcome to Scala version 2.10.0-20121007-145615-65a321c63e (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_35). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> import scala.reflect.runtime.universe._ 
import scala.reflect.runtime.universe._ 

scala> typeOf[List[Int]] 
res0: reflect.runtime.universe.Type = scala.List[Int] 

scala> res0 match { case TypeRef(_, _, args) => args } 
res1: List[reflect.runtime.universe.Type] = List(Int) 

scala> res1.head 
res2: reflect.runtime.universe.Type = Int 

संपादित यहाँ (निम्नलिखित एक discussion on scala-internals) एक ही बात को प्राप्त करने के एक से थोड़ा अच्छे तरीका है:

scala> res0.asInstanceOf[TypeRefApi].args 
res1: List[reflect.runtime.universe.Type] = List(Int) 
+0

इस पर स्कैला-इंटर्नल मेलिंग सूची पर चर्चा की गई: https://groups.google.com/forum/#!msg/scala-internals/R1iZXfotqds/zqq8QjMJj74J –

+0

ऐसा प्रतीत होता है! - हालांकि (आपके लिंक का संदर्भ) मैं आपके विवाद को भी साझा करता हूं! मैं यहां अपने स्वयं के अनुभव को एक तर्क के रूप में इंगित करता हूं कि यह कम से कम विस्मय के सिद्धांत का उल्लंघन क्यों करता है। – Tim

+0

https://groups.google.com/d/topic/scala-internals/56KRF98Mdjo/discussion –

16

Scala 2.11 के साथ शुरू, तो आप बस का उपयोग कर सकते हैं:

yourGenericType.typeArgs.head 

macros changelog बिंदु संख्या 14

संबंधित मुद्दे