2010-11-07 9 views
5

मुझे अपने केस कक्षाओं को डिजाइन करने में कुछ कठिनाइयां मिलीं। एक सरलीकृत संस्करण की तरह लग रहा:स्कैला केस क्लास पदानुक्रम

abstract class Base(s: Option[String]) { 
    //code 
} 

case class CaseClass(s: Option[String] = None) extends Base(s) { 
    //code 
} 

और मैं एक तरीका है जहाँ मैं की तरह कुछ करने के लिए करना चाहते हैं:

def method(base : Base) = { 
    //code 
    base copy (s = Some("string")) 
    } 
बेशक

मैं:

value copy is not a member of Base 

तो मैं क्या चाहते करने के लिए मेरी बेस क्लास (जो केस क्लास नहीं है) के आधार पर एक नया उदाहरण बनाते हैं। जाहिर है कि कोई ऐसा नहीं कर सकता है। लेकिन आप इसे एक सुरुचिपूर्ण तरीके से कैसे हल करेंगे?

अग्रिम धन्यवाद!

+0

संबंधित प्रश्न: http://stackoverflow.com/questions/2911562/case-class-copy-method-abstraction –

+1

http://scala-programming-language.1934581.n4.nabble.com/Question-on- केस-क्लास-एंड-कॉपी-विधि-td1936310.html –

उत्तर

3

जिस व्यवहार को आप प्राप्त करने का प्रयास कर रहे हैं वह लागू नहीं है। copy एक केस क्लास की विधि संकलक द्वारा स्वत: उत्पन्न होती है, और एक बार जब आप अपने कार्यान्वयन के लिए copy नामक एक विधि जोड़ते हैं, तो कंपाइलर कोई चीनी उत्पन्न नहीं करेगा।

आप लक्षण के साथ copy reimplement कर सकते हैं, लेकिन यह के रूप में लचीला के रूप में उत्पन्न एक (आप आधार विशेषता, copy और method कार्यान्वयन हर बार एक मामले वर्ग परिवर्तन के क्षेत्र सेट अद्यतन करने के लिए होगा) नहीं होगा:

sealed trait Base[T] { 
    val s: Option[String] 
    def copy(s: Option[String]) : T 
} 

case class CaseClass(override val s: Option[String] = None) extends Base[CaseClass] { 
    override def copy(s: Option[String]) = CaseClass(s) 
} 

def method[T <: Base[T]](base : Base[T]) = base copy (s = Some("strng")) 

वैकल्पिक रूप से, आप method इस प्रकार लागू कर सकते हैं:

case class CaseClass(s: Option[String] = None) 

def method[X <: {def copy(s: Option[String]):X}](base : X) = 
    base copy(s = Some("string")) 

scala> method(CaseClass()) 
res4: CaseClass = CaseClass(Some(string)) 

इस प्रकार आपको Base विशेषता की आवश्यकता नहीं होगी, और यदि आपके केस क्लासेस बदलते हैं तो बदलावों की संख्या को कम करें।

+0

मुझे पहला सुझाव पसंद है। धन्यवाद! – tbruhn

7

यदि आप अपनी बेस क्लास को पैरामीटर करते हैं और वहां अमूर्त प्रति विधि को भी परिभाषित करते हैं, तो आप प्रतिलिपि प्रतिलिपि विधि से अपने स्वयं के प्रकारों को वापस कर सकते हैं। इस मामले में, आप केस क्लास को केस क्लास वापस करने की इच्छा रखते हैं।

abstract class Base[T](s: Option[String]) { 
    def copy(in: Option[String]) : T 
} 

case class CaseClass(s: Option[String]) extends Base[CaseClass](s) { 
    def copy(in: Option[String]) = CaseClass(in) 
} 

case class OtherClass(s: Option[String]) extends Base[OtherClass](s) { 
    def copy(in: Option[String]) = OtherClass(in) 
} 

def method[T <: Base[T]](base: T) : T = { 
    base.copy(Some("String")) 
} 


scala> method(CaseClass(None)) 
res1: CaseClass = CaseClass(Some(String)) 

scala> method(OtherClass(Some("hi"))) 
res2: OtherClass = OtherClass(Some(String)) 

बेस के अन्य उपवर्गों अपने स्वयं के प्रकार लौट आते हैं। #method पर प्रकार पैरामीटर बेस [टी] के ऊपरी बाउंड के साथ परिभाषित किया गया है। इसका मतलब है कि टी किसी उप-प्रकार का बेस [टी] होना चाहिए और यह आपको उस विधि के पैरामीटर के रूप में केस क्लास और अन्य क्लास के उदाहरणों की आपूर्ति करने की अनुमति देता है।

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

  • कोई संबंधित समस्या नहीं^_^