स्केल में पैटर्न मिलान वैरिएबल के साथ काम क्यों नहीं करता है?


113

निम्नलिखित कार्य करें:

def fMatch(s: String) = {
    s match {
        case "a" => println("It was a")
        case _ => println("It was something else")
    }
}

यह पैटर्न अच्छी तरह से मेल खाता है:

scala> fMatch("a")
It was a

scala> fMatch("b")
It was something else

मैं जो करना चाहता हूं वह निम्नलिखित है:

def mMatch(s: String) = {
    val target: String = "a"
    s match {
        case target => println("It was" + target)
        case _ => println("It was something else")
        }
}

यह निम्नलिखित त्रुटि देता है:

fMatch: (s: String)Unit
<console>:12: error: unreachable code
               case _ => println("It was something else")

मुझे लगता है कि ऐसा इसलिए है क्योंकि यह सोचता है कि लक्ष्य वास्तव में एक ऐसा नाम है जिसे आप इनपुट करना चाहते हैं। दो सवाल:

  1. यह व्यवहार क्यों? क्या मामला केवल मौजूदा वैरिएबल के दायरे में नहीं दिख सकता है, जिनके पास उपयुक्त प्रकार है और जो पहले उपयोग करते हैं और यदि कोई नहीं पाया जाता है, तो लक्ष्य को एक नाम के रूप में समझें?

  2. क्या इसके आसपास कोई कार्य है? वेरिएबल्स के खिलाफ मैच करने का कोई तरीका? अंतत: अगर कोई बयान का उपयोग कर सकता है, लेकिन मैच का मामला अधिक सुरुचिपूर्ण है।



1
मेरा मानना ​​है कि यह प्रश्न, कोड और उत्तर Scala 2.12.x के रूप में पुराना है। यह अच्छा होगा यदि संस्करण जिस पर लागू होता है उसे प्रश्न के भाग के रूप में उल्लेख किया गया था।
शंकु

जवाबों:


217

आप जो देख रहे हैं वह एक स्थिर पहचानकर्ता है । स्काला में, इन्हें या तो अपरकेस लेटर से शुरू करना चाहिए, या बैकटिक्स से घिरा होना चाहिए।

ये दोनों आपकी समस्या के समाधान होंगे:

def mMatch(s: String) = {
    val target: String = "a"
    s match {
        case `target` => println("It was" + target)
        case _ => println("It was something else")
    }
}

def mMatch2(s: String) = {
    val Target: String = "a"
    s match {
        case Target => println("It was" + Target)
        case _ => println("It was something else")
    }
}

गलती से उन चरों को संदर्भित करने से बचने के लिए जो पहले से ही संलग्न दायरे में मौजूद थे, मुझे लगता है कि यह समझ में आता है कि डिफॉल्ट व्यवहार लोअरकेस पैटर्न के लिए है चर नहीं और स्थिर पहचानकर्ता हैं। केवल जब आप ऊपरी मामले के साथ या पीछे के टिक्स के साथ शुरुआत करते हैं, तो क्या आपको पता होना चाहिए कि यह आसपास के दायरे से आता है।


3
मुझे यकीन है कि यह एर्लैंग से आता है, जहां चर एक बड़े अक्षर से शुरू होते हैं और निचले मामले में प्रतीक होते हैं।
एमिल इवानोव

11
ध्यान दें कि targetएक मान ( val) है, और एक चर नहीं है ( var)। यह चर के साथ काम नहीं करता है।
लुइगी प्लिंज

अपरकेस? शेड्स ऑफ़ फोरट्रान। कमजोर, मार्टिन, कमजोर।
मालवोलियो

13
@ ईमिल वास्तव में, स्काला में पूंजीकृत पहचानकर्ता स्थिरांक निरूपित करते हैं। इसलिए अपरकेस आइडेंटिफ़ायर पर एक पैटर्न का मिलान एक स्थिर की तुलना करने के लिए किया जाता है। यह गंभीरता से सामान की तरह मदद करता है Nil, जो मुझे लगता है कि असली कारण है।
डैनियल सी। सोबरल

लगता है जैसे कोई thisइसके खिलाफ मैच करने के लिए एक स्थिर पहचानकर्ता के रूप में उपयोग नहीं कर सकता है, केवल एक समानता गार्ड का उपयोग कर रहा है case x if x == this =>। संभवतः एक वाक्यात्मक सीमा है, अन्यथा इसे शब्दार्थ में कम से कम काम करना चाहिए object
नादेर घनबारी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.