2011-08-23 7 views
17

कक्षा चर के मान की पहचान करने के लिए मैं "मैच" कथन का उपयोग कैसे कर सकता हूं? निम्नलिखित अमान्य है, और मैं एक स्वीकार्य संस्करण नहीं मिल सकता है - अगर अलावा अन्य ... यदि किसी और ... और ...मैं स्कैला "मैच" कथन में कक्षाओं से कैसे मिलान कर सकता हूं?

val c: Class[_] = classOf[Int] 
val what = c match { case classOf[Int] => "int!"; case classOf[Float] => "float!" } 

संकलक शिकायत: error: not found: type classOf

और निश्चित रूप से कोई लाभ नहीं हुआ Int.class तरह

c match { case Class[Int] => "int!"; case Class[Float] => "float!" } 
error: type Class of type Class does not take type parameters. 

मैं भी कोशिश की है वेरिएंट, सभी:, मैं Class[Int] उपयोग कर सकते हैं नहीं है, क्योंकि है कि प्रकार की जानकारी मिटा दिया जाता है। (और मैं वास्तव में स्ट्रिंग्स में कनवर्ट नहीं करना चाहता हूं: मुझे लगता है कि कंपाइलर कैच का नाम बदला/स्थानांतरित किया जाना महत्वपूर्ण है।)

क्या मैं घना हो रहा हूं, या क्या मैं स्कैला अंधा स्थान में ठोकर खा रहा हूं?

+1

ठीक है, नीचे दिए गए उत्तर जवाब के लिए सही है (और धन्यवाद कर रहे हैं!) लेकिन यह तेजी से दिखाई देता है * यह * स्कैला में एक प्रकार का बदसूरत छेद है। कक्षाएं सिंगलेट हैं, इसलिए कोई कारण नहीं है कि उन्हें कुशलतापूर्वक मिलान करने के लिए उन्हें चर के लिए असाइन करना होगा - न ही रक्षक या अलग-अलग बयान के रूप में लिखे गए आईएफएस की एक कैस्केडिंग श्रृंखला का उपयोग करना। लेकिन जाहिर है, यह है। – Tim

उत्तर

18

यदि आप एक स्थिर पहचानकर्ता बनाते हैं तो आप वर्ग मूल्यों पर मिलान कर सकते हैं (यानी। एक वैल) उनके लिए,

scala> val c: Class[_] = classOf[Int] 
c: Class[_] = int 

scala> val ClassOfInt = classOf[Int] 
ClassOfInt: java.lang.Class[Int] = int 

scala> val ClassOfFloat = classOf[Float] 
ClassOfFloat: java.lang.Class[Float] = float 

scala> val what = c match { 
    |  case ClassOfInt => "int!" 
    |  case ClassOfFloat => "float!" 
    | } 
what: String = int! 

ध्यान दें कि आप प्रकार पर से मेल नहीं कर सकते हैं (यानी। कक्षा [इंट]) क्योंकि विलोपन मतलब यह है कि कक्षा [टी] के विभिन्न प्रकार instantiations कार्यावधि में अप्रभेद्य हैं ... इसलिए नीचे

scala> val what = c match { 
    |  case _: Class[Int] => "int!" 
    |  case _: Class[Float] => "float!" 
    | } 
warning: there were 2 unchecked warnings; re-run with -unchecked for details 
what: java.lang.String = int! 
+1

स्थिर पहचानकर्ता - हाँ, मुझे इससे डर था। घृणित। "ध्यान दें कि आप प्रकार (यानी कक्षा [Int]) से मेल नहीं खा सकते हैं" - हाँ, प्रश्न में नोट किया गया। फिर भी आपका धन्यवाद! – Tim

+0

(मुझे यह भी ध्यान रखना चाहिए कि यह उत्तर नीचे दिए गए की तुलना में संभावित रूप से अधिक कुशल है, इसलिए यह जो कुछ मैं ढूंढ रहा हूं उसके करीब है। धन्यवाद!) – Tim

+1

एक महत्वपूर्ण नोट: 'वैल' का नाम ऊपरी मामले से शुरू होना चाहिए। – vpipkt

26

वर्बोज़ मामले तुलना काम करता है:

val what = c match { 
    case q if q == classOf[Int] => "int!" 
    case q if q == classOf[Float] => "float!" 
} 
बेशक

, एक लोअर केस पहचानकर्ता जा रहा है, classOf वैसे भी एक मामले बयान में सीधे काम नहीं करना चाहिए। हालांकि, न तो एक भाग निकले

case `classOf`[Int] 

काम इस मामले में है, तो आप if -guard साथ जाना होगा करता है।

+0

हां, if-guard काम करता है ... 'if' कथन को 'if/else' कथन के सेट में परिवर्तित कर रहा है। बदसूरत, लेकिन काफी सही है। धन्यवाद! – Tim

+0

इस प्रश्न के लिए चालाक समाधान – javadba

0

चेतावनी मैं एक ही समस्या है और एक 'स्थिर पहचानकर्ता' में वर्ग रखने का सामना करना पड़ा है कि व्यावहारिक नहीं था । मैंने पाया कि अगली सबसे अच्छी बात यह है कि 'अगर' बयान 'साफ' हो।

इस विधि का उपयोग करना:

private def is[T <: AnyRef : Manifest](implicit cls: Class[_]) = 
    cls == manifest[T].runtimeClass 

मैं लिख सकते हैं:

implicit val arg = cls 
    if (is[ClassA]) ... 
    else if (is[ClassB]) ... 
    ... 
    else throw new IllegalArgumentException("Unknown class: " + cls) 
+0

हा हा। मैंने अभी अपना जवाब फिर से पाया लेकिन मैं इसके लिए वोट नहीं दे सकता। –

0

विरासत पर विचार करने के लिए:

val what = c match { 
    case q if classOf[Int].isAssignableFrom(q) => "int!" 
    case q if classOf[Float].isAssignableFrom(q) => "float!" 
} 
संबंधित मुद्दे