2013-01-11 15 views
5

मैं है कोड:त्रुटि

class A { 
    override def toString = "object class A" 
} 

class B extends A { 
    override def toString = "object class B" 
} 

class Cell[+T](init: T) { 
    private[this] var current: T = init 
    def get: T = current 
    def set(x: T) { current = x } 
} 

val cB = new Cell[B](new B) 
println(cB.get) 
val cA: Cell[A] = cB 
println(cA.get) 

लेकिन मैं लाइन में त्रुटि है: def set(x: T) { current = x }

error: covariant type T occurs in contravariant position in type T of value x def set(x: T) { current = x }

के बारे में बताएं, कृपया

+1

व्यावहारिक जवाब के अलावा, तुम क्यों स्पष्ट निजी संदर्भ और गेटर/सेटर की आवश्यकता है:


एक लंबे समय तक, और अधिक औपचारिक/व्यापक जवाब के लिए, इस सवाल देखते हैं? स्कैला आपके लिए यह करता है: 'कक्षा सेल [+ टी] (वैल टी: टी) {...} ' –

उत्तर

5

एक प्रकार के लिए contravariant स्थान नहीं हैं (दूसरों के बीच) किसी भी स्थिति जो आपको उस विधि के उदाहरण को एक विधि में पारित करने की अनुमति देती है। तो सभी विधि पैरामीटर प्रकार contravariant पदों में हैं। चूंकि आपने टी को कॉन्वेंट (+T) घोषित किया है, इसलिए संकलक इसकी अनुमति नहीं देगा। आपका केवल विकल्प हैं:

  • मेकअप T अपरिवर्तनीय
  • सेट विधि ऐसी है कि वह Cell का एक नया उदाहरण देता है और इस प्रकार Cell अपरिवर्तनीय हो जाता है संशोधित।
  • सेट विधि निकालने के लिए, यह भी Cell अपरिवर्तनीय

बनाने संकलक के रूप में आप इसे लागू आप एक निर्धारित विधि की अनुमति दी है, उस प्रकार प्रणाली असुरक्षित होगा, क्योंकि यह आप लिखने के लिए अनुमति होगी:

val cs:Cell[String] = new Cell("") 
val ca:Cell[Any] = cs 
ca.set(5) 
val s:String = cs.get //boom 
+0

' cs.set (5) ' –

+0

के बदले' ca.set (5) 'होना चाहिए, धन्यवाद यह –

4

संक्षिप्त उत्तर यह है कि आपके पास एक परिवर्तनीय कंटेनर नहीं है जो कॉन्वर्सेंट है। इस संकलित है, तो अपने उदाहरण में मान लिया जाये, अंतिम दो पंक्तियों को पढ़ सकता है:

val cA: Call[A] = cB 
cA.set(new A) 

पहली पंक्ति की अनुमति दी जाएगी, क्योंकि एक Cell[B]+T के उपयोग के कारण एक Cell[A] है। और फिर दूसरी पंक्ति भी अनुमति है - निश्चित रूप से आप A को पकड़ने के लिए Cell[A] सेट कर सकते हैं।

लेकिन अब, cB.getA का एक उदाहरण देता है, B नहीं! यह कोई समझ नहीं आता है, और इस विरोधाभास को हल करने का कोई तरीका नहीं है जबकि सेल के प्रकार पैरामीटर में कॉन्वर्सिस को अनुमति देता है। Scala covariance/contravariance