2012-08-25 9 views
45

में यह instantiating स्काला 2.10 में कैसे मैं स्ट्रिंग से एक वर्ग उत्पन्न करते हैं (शायद, उपकरण बॉक्स एपीआई का उपयोग) बाद में स्काला के प्रतिबिंब के साथ instantiated जा करने के लिए?स्ट्रिंग से एक वर्ग जनरेट कर रहा है और स्काला 2.10

उत्तर

52

W.r.t संकलन toolboxes केवल भाव = वापसी मान, लेकिन नहीं संकलन परिणामों के साथ वर्ग या फ़ाइलें/बाइट सरणियों जिसके परिणामस्वरूप चला सकते हैं।

हालांकि यह अभी भी प्राप्त करने के लिए आप क्या चाहते हैं संभव है, के बाद से स्काला में यह अंतर्निहित मानों का उपयोग मूल्य स्तर तक प्रकार के स्तर से जाने के लिए बहुत आसान है:

संपादित। 2.10.0-आरसी 1 में ToolBox के कुछ तरीकों का नाम बदल दिया गया है। parseExpr अब parse है, और runExpr अब eval कहा जाता है।

scala> import scala.reflect.runtime._ // requires scala-reflect.jar 
             // in REPL it's implicitly added 
             // to the classpath 
             // but in your programs 
             // you need to do this on your own 
import scala.reflect.runtime 

scala> val cm = universe.runtimeMirror(getClass.getClassLoader) 
cm @ 41d0fe80: reflect.runtime.universe.Mirror = JavaMirror with scala.tools.nsc.interpreter.IMain$TranslatingClassLoader... 

scala> import scala.tools.reflect.ToolBox // requires scala-compiler.jar 
              // in REPL it's implicitly added 
              // to the classpath 
              // but in your programs 
              // you need to do this on your own 
import scala.tools.reflect.ToolBox 

scala> val tb = cm.mkToolBox() 
tb: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] = [email protected] 

scala> tb.runExpr(tb.parseExpr("class C; scala.reflect.classTag[C].runtimeClass")) 
res2: Any = class __wrapper$1$f9d572ca0d884bca9333e251c64e980d$C$1 

अद्यतन # 1। यदि आपको java.lang.Class की आवश्यकता नहीं है और केवल संकलित कक्षा को तुरंत चालू करने की आवश्यकता है, तो आप new C सीधे runExpr पर सबमिट की गई स्ट्रिंग में लिख सकते हैं।

अद्यतन # 2। runExpr वैरिएबल नामों से रनटाइम मानों तक कस्टम मैपिंग का भी उपयोग करना संभव है। उदाहरण के लिए:

scala> val build = scala.reflect.runtime.universe.build 
build: reflect.runtime.universe.BuildApi = [email protected] 

scala> val x = build.setTypeSignature(build.newFreeTerm("x", 2), typeOf[Int]) 
x: reflect.runtime.universe.FreeTermSymbol = free term x 

scala> tb.runExpr(Apply(Select(Ident(x), newTermName("$plus")), List(Literal(Constant(2))))) 
res0: Any = 4 

इस उदाहरण में मैं एक नि: शुल्क अवधि 2 के एक मूल्य है कि बनाने के (मूल्य एक आदिम होना जरूरी नहीं करता है - यह अपने कस्टम वस्तु हो सकता है) और इसे करने के लिए एक पहचानकर्ता बाँध। इस मान का उपयोग उस कोड में किया जाता है जो संकलित और टूलबॉक्स द्वारा चलाया जाता है।

उदाहरण मैनुअल एएसटी असेंबली का उपयोग करता है, लेकिन एक स्ट्रिंग को पार करने वाला एक फ़ंक्शन लिखना संभव है, अनबाउंड पहचानकर्ताओं को पता चलता है, कुछ मैपिंग में उनके लिए मूल्य दिखता है और फिर संबंधित निशुल्क शर्तों को बनाता है। हालांकि स्कैला 2.10.0 में ऐसा कोई फ़ंक्शन नहीं है।

+0

धन्यवाद! एक फॉलो-अप: स्केल के प्रतिबिंब के साथ इस लौटे 'java.lang.Class' पर एक संभाल पाने का कोई तरीका है या मुझे बस पुराने पुराने जावा के साथ रहना होगा? –

+2

निश्चित रूप से। ' .classSymbol का प्रयोग करें ()', जहां = 'scala.reflect.runtime.universe.runtimeMirror (.getClassLoader )'। फिर आपको एक स्काला प्रतिबिंब प्रतीक मिलता है, जिसे स्कैला प्रतिबिंब एपीआई के साथ निरीक्षण किया जा सकता है। –

+0

आपने 'reflect.runtime.currentMirror' और 'scala.reflect.classTag [सी]।' ClassOf [सी] 'के बजाय' runtimeClass' 'के बजाय' universe.runtimeMirror (getClass.getClassLoader) 'का उपयोग क्यों किया? यह मेरे अंत में ठीक काम करने के लिए बाहर निकला। धन्यवाद मदद के लिए बहुत कुछ, बीटीडब्ल्यू! –

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