2013-06-17 9 views
5

लिए मैं वर्ग पर एक पैटर्न मैच करने की जरूरत है। समस्या यह है कि मुझे लम्बे समय से मेल खाने में कुछ समस्याएं हैं।स्काला: कैसे पैटर्न मैच scala.Long और java.lang.Long

मैं उसी तरह से scala.Long और java.lang.Long संभालने की ज़रूरत है, लेकिन क्यों मैं उन्हें दोनों ही मामलों में घोषित करने के लिए की जरूरत है?

def test(typ: Class[_]) { 
    typ match { 
     case q if q == classOf[Long] => println("scala long...") 
    } 
    } 

    val scalaLongField: java.reflect.Field = ...... 
    val javaLongField: java.reflect.Field = ...... 
    test(scalaLongField.getType) // prints "scala long..." 
    test(javaLongField.getType) // scala.MatchError: class java.lang.Long (of class java.lang.Class) 

वहाँ एक रास्ता उन्हें एक उदाहरण लेकिन सिर्फ वर्ग बिना ही संभाल करने है:

यहाँ एक उदाहरण है?

उत्तर

3

कारण है कि java.lang.Long और Long विभिन्न वर्गों रहे हैं। जावा में, वहाँ java.lang.Long.class और Long.TYPE बीच एक अंतर है। इसी तरह, स्काला में, classOf[Long] और classOf[java.lang.Long] अलग हैं।

आप वर्गों पर पैटर्न मैच देखना चाहते हैं, तो आप सहायक है कि के लिए unapply तरीकों बना सकते हैं:

object ScalaLong { 
    // Internal helper: 
    private def matchClass[T](c: Class[_], as: Class[T]): Option[Class[T]] = 
    if (as.isAssignableFrom(c)) Some(as) 
    else None; 

    // Matches wrapped Long classes. 
    object LongObject { 
    def unapply(c: Class[_]): Option[Class[java.lang.Long]] = 
     matchClass(c, classOf[java.lang.Long]); 
    } 
    // Matches primitive long classes. 
    object LongPrim { 
    def unapply(c: Class[_]): Option[Class[Long]] = 
     matchClass(c, classOf[Long]); 
    } 

    // -- Test: 

    def check(clz: Class[_]) = 
    clz match { 
     case LongPrim(c) => println("Long primitive: " + c); 
     case LongObject(c) => println("Long object: " + c); 
     case _    => println("Other: " + clz); 
    } 


    class Example { 
    val l1: scala.Long = 1L; 
    val l2: java.lang.Long = 1L; 
    val l3: java.lang.Integer = 1; 
    } 

    def main(argv: Array[String]) { 
    for(name <- Seq("l1", "l2", "l3")) 
     check(classOf[Example].getMethod(name).getReturnType()); 
    } 
} 

आम तौर पर, आप अलग से classOf[Long] और classOf[java.lang.Long] का इलाज करना होगा। शायद, यदि आप वर्णन करते हैं कि आपको उनके साथ क्या करने की ज़रूरत है, तो हम आपके विशिष्ट कार्य के लिए बेहतर समाधान पा सकते हैं।

4

यह सीधे काम करना चाहिए:

object LongTest { 
    def test(value: Any): Boolean = value match { 
    case l: Long => true 
    case _ => false 
    } 

    def run() { 
    println(test(1L)) 
    println(test(new java.lang.Long(1L))) 
    } 
} 

LongTest.run() // true and true 

यह मेरे लिए स्पष्ट है कि आप उदाहरण के बजाय वर्गों का मिलान करना चाहते नहीं था। मुझे यकीन नहीं है कि मैं समझता हूं कि आप वास्तव में क्या चाहते हैं। इस कदर?

object LongTest { 
    def test(clazz: Class[_]): Boolean = 
    clazz == classOf[Long] || clazz == classOf[java.lang.Long] 

    def run() { 
    println(test(1L.getClass)) 
    println(test(new java.lang.Long(1L).getClass)) 
    } 
} 

LongTest.run() // true and true 

या एक पैटर्न मैच के रूप में:

def test(clazz: Class[_]): Boolean = clazz match { 
    case q if q == classOf[Long] || q == classOf[java.lang.Long] => true 
    case _ => false 
    } 
+0

सिर्फ अगर मैं मूल्य है! मैं इस की जरूरत है काम करने के लिए जब मैं केवल वर्ग है, जैसे मैं प्रश्न में कहा: "? वहाँ एक तरीका है कि उन्हें एक उदाहरण लेकिन सिर्फ वर्ग बिना ही संभाल करने है" – maklemenz

+1

@mklemenz आपको अपने उदाहरणों को बिल्कुल वही करने के लिए अच्छी तरह से सेवा दी जाएगी जो आप चाहते हैं। आपके नमूना विधियों के बहुमत (2/3) में मूल्य होता है, केवल एक में केवल कक्षा होती है। –

+0

मैंने प्रश्न संपादित किया है – maklemenz

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