2012-03-10 14 views
8

मैं निम्नलिखित कोड है:स्काला - मिलान पैटर्न में एक मिलान आइटम के पद पर नियुक्ति

class Animal(hair: Option[Hair]) 

class Cat(var hair: Option[Hair]) extends Animal(hair) 
class Dog(var hair: Option[Hair]) extends Animal(hair) 
class Sheep(var hair: Option[Hair]) extends Animal(hair) 

//then somewhere else: 

def what(animal: Animal) { 

    animal match { 
    case Cat(hair) => println("processing cat, hair=" + hair) 
    case Dog(hair) => println("processing dog, hair=" + hair) 
    case Sheep(hair) => { 
     println("processing sheep, cutting hair...") 
     hair = None 
    } 
    } 
} 

प्रश्न हैं:

1) पैटर्न मिलान एक भेड़ के साथ सफल होता है, तो मैं कैसे उपयोग कर सकते हैं यह बालों है और इसे बदलो? इसने वैल के पुनर्मूल्यांकन के बारे में शिकायत की, और फिर मैंने var को कन्स्ट्रक्टर में रखा है लेकिन अभी भी ...

2) एक और तरीका मैं सोच सकता हूं कि पूरे मिलान किए गए मान को एक चर के लिए असाइन करना है, क्या कोई तरीका है किसी मामले में कुछ केस क्लास कन्स्ट्रक्टर पैटर्न से मिलान किए गए मान को बाध्य करें?

(मुझे पता है कि मैं शायद s: Sheep जैसे पैटर्न पर मिलान कर सकता हूं और फिर s.changeHairTo(None) पर कॉल कर सकता हूं लेकिन यह सबसे कमजोर तरीका है)।

उत्तर

25

आप @ का उपयोग अपने संस्करण

class Animal(hair: Option[Hair]) 
case class Cat(var hair: Option[Hair]) extends Animal(hair) 
case class Dog(var hair: Option[Hair]) extends Animal(hair) 
case class Sheep(var hair: Option[Hair]) extends Animal(hair) 

def what(animal: Animal) { 
    animal match { 
    case Cat(hair) => println("processing cat, hair=" + hair) 
    case Dog(hair) => println("processing dog, hair=" + hair) 
    case s @ Sheep(hair) => { 
     println("processing sheep, cutting hair...") 
     //cut(hair) 
     s.hair = None 
    } 
    } 
} 

में चर के लिए पूरे पैटर्न बाध्य करने के लिए कर सकते हैं लेकिन आप var उपयोग करने के लिए नहीं है। यहां आपके स्निपेट का अधिक कार्यात्मक संस्करण है। what यहां Sheep काटने के बाद NoneHair के साथ आता है।

trait Animal 
case class Cat(hair: Option[Hair]) extends Animal 
case class Dog(hair: Option[Hair]) extends Animal 
case class Sheep(hair: Option[Hair]) extends Animal 

def what(animal: Animal): Animal = 
    animal match { 
    case Cat(hair) => 
     println("processing cat, hair=" + hair) 
     animal 
    case Dog(hair) => 
     println("processing dog, hair=" + hair) 
     animal 
    case Sheep(hair) => { 
     println("processing sheep, cutting hair...") 
     //cut(hair) 
     Sheep(None) 
    } 
    } 
4

यह काम नहीं करता है, क्योंकि विभिन्न "बालों" से मेल खाने वाले पैटर्न में भेड़ के ऑब्जेक्ट से निकाला गया है, इसलिए यह भेड़ का क्षेत्र नहीं है, बल्कि केस ब्लॉक के संदर्भ में एक चर है। आप इसे इस तरह कर सकता है:

class Hair 

trait Animal { 
    var hair: Option[Hair] 
} 
case class Cat(var hair: Option[Hair]) extends Animal 
case class Dog(var hair: Option[Hair]) extends Animal 
case class Sheep(var hair: Option[Hair]) extends Animal 

//then somewhere else: 

def what(animal: Animal) { 

    animal match { 
    case Cat(hair) => println("processing cat, hair=" + hair) 
    case Dog(hair) => println("processing dog, hair=" + hair) 
    case Sheep(hair) => { 
     println("processing sheep, cutting hair...") 
     animal.hair = None 
    } 
    } 
} 

बस पशु बता यह एक अस्थायी क्षेत्र बाल है और आप सही प्रकार के लिए यह कास्टिंग के बिना यह निर्धारित कर सकते हैं।

+0

हालांकि यह काम करता है, मैं बेहतर विकल्प के रूप में 4e6 का पहला ब्लॉक पसंद करूंगा। आप मामले के बयान में जानते हैं कि आप 'भेड़' से निपट रहे हैं, इसलिए सभी 'पशु को म्यूटेबल बालों से निपटने के लिए कोई आवश्यकता नहीं है। आम तौर पर बोलते हुए, उत्परिवर्तन को कम करना एक अच्छी बात है, और वैकल्पिक दृष्टिकोण बिल्लियों और कुत्तों को अपरिवर्तनीय बाल भी देता है। –

+0

मैं दोनों बिंदुओं में पूरी तरह से आपसे सहमत हूं। लेकिन उनकी बिल्ली और कुत्ते वर्गों में पहले से ही परिवर्तनीय बाल क्षेत्र हैं ;-) – drexin

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