2013-08-17 8 views
8

का उपयोग करके कास्टिंग टाइप करें एक जावा विधि दी गई है जो किसी दिए गए स्ट्रिंग के लिए java.lang.Object एस देता है। मैं इस विधि को स्कैला विधि में लपेटना चाहता हूं जो लौटाए गए उदाहरणों को कुछ प्रकार T में परिवर्तित करता है। यदि रूपांतरण विफल रहता है, तो विधि None वापस करनी चाहिए। मैं यह करने के लिए कुछ इसी तरह रहा हूँ:टाइप पैरामीटर

def convert[T](key: String): Option[T] = { 
    val obj = someJavaMethod(key) 
    // return Some(obj) if obj is of type T, otherwise None 
} 

convert[Int]("keyToSomeInt") // yields Some(1) 
convert[String]("keyToSomeInt") // yields None 

(कैसे) यह लक्ष्य प्राप्त किया जा सकता है स्काला के प्रतिबिंब एपीआई का उपयोग कर? मुझे अच्छी तरह से पता है कि convert के हस्ताक्षर को बदला जाना पड़ सकता है।

उत्तर

12

है यही कारण है कि एक ClassTag के लिए करता है, तो:

import reflect.ClassTag 

def convert[T : ClassTag](key: String): Option[T] = { 
    val ct = implicitly[ClassTag[T]] 
    someJavaMethod(key) match { 
    case ct(x) => Some(x) 
    case _ => None 
    } 
} 

यह एक निकालने का परीक्षण करने और एक ही समय में उचित प्रकार के कलाकारों के रूप में इस्तेमाल किया जा सकता।

उदाहरण:

scala> def someJavaMethod(s: String): AnyRef = "e" 
someJavaMethod: (s: String)AnyRef 

[...] 

scala> convert[Int]("key") 
res4: Option[Int] = None 

scala> convert[String]("key") 
res5: Option[String] = Some(e) 

संपादित: फिर भी नोट है कि एक ClassTagनहीं स्वचालित रूप से Unbox बॉक्स्ड पुरातन करता है। इसलिए, उदाहरण के लिए, convert[Int]("a") कभी काम नहीं करेगा, क्योंकि जावा विधि AnyRef लौटाती है, इसे convert[java.lang.Integer]("a"), और अन्य आदिम प्रकारों के लिए भी होना चाहिए।

Typeable के साथ माइल्स का उत्तर स्वचालित रूप से उन एज मामलों का ख्याल रखना प्रतीत होता है।

15

आप की कोशिश कर सकते shapeless के Typeable,

scala> import shapeless._ ; import syntax.typeable._ 
import shapeless._ 
import syntax.typeable._ 

scala> def someJavaMethod(key: String): AnyRef = 
    | key match { 
    |  case "keyToSomeInt" => 23.asInstanceOf[AnyRef] 
    |  case "keyToSomeString" => "foo" 
    | } 
someJavaMethod: (key: String)AnyRef 

scala> def convert[T: Typeable](key: String): Option[T] = 
    | someJavaMethod(key).cast[T] 
convert: [T](key: String)(implicit evidence$1: shapeless.Typeable[T])Option[T] 

scala> convert[Int]("keyToSomeInt") 
res0: Option[Int] = Some(23) 

scala> convert[String]("keyToSomeString") 
res1: Option[String] = Some(foo) 

scala> convert[String]("keyToSomeInt") 
res2: Option[String] = None 

scala> convert[Int]("keyToSomeString") 
res3: Option[Int] = None 
+0

धन्यवाद इस के लिए बहुत बहुत। मैंने अपना स्वयं का 'सुरक्षितकास्ट [टी: क्लासटाग]' विकल्प [किसी भी] से एक निहित रूपांतरण पर किया लेकिन ध्यान दिया कि प्राइमेटिव हमेशा किसी को वापस नहीं कर रहे थे। टाइप करने योग्य I का उपयोग करके शरीर को एक साधारण 'opt.flatMap (_। Cast [टी]) में बदल दिया गया है और यह बहुत अच्छा काम करता है। – ShawnFumo

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