2012-07-30 15 views
6

में होता है मैं स्काला में मेरा पहला कदम आगे बढ़ रहा हूँ और मैं निम्नलिखित कोड काम करता है बनाने के लिए करना चाहते हैं:covariant प्रकार टी अपरिवर्तनीय स्थिति

trait Gene[+T] { 
    val gene: Array[T] 
} 

त्रुटि संकलक देता है कि जाता है: covariant type T occurs in invariant position in type => Array[T] of value gene

मैं जानता हूँ कि मैं कुछ ऐसा कर सकता है:

trait Gene[+T] { 
    def gene[U >: T]: Array[U] 
} 

लेकिन क्योंकि मैं एक मूल्य की जरूरत है इस समस्या का समाधान नहीं करता है: pratically कि मैं क्या कहने की कोशिश कर रहा हूँ कि "मैं इन की परवाह नहीं है विचार प्रकार, मुझे पता है कि जीनों में एक जीन क्षेत्र होगा जो इसकी सामग्री वापस करेगा "। (यहां + टी है क्योंकि मैं type Genome = Array[Gene[Any]] जैसे कुछ करना चाहता हूं और फिर इसे एकल जीन कक्षाओं के खिलाफ एक रैपर के रूप में उपयोग करना चाहता हूं, इसलिए मेरे पास एक विषम सरणी प्रकार हो सकता है) क्या इसे स्कैला में करना संभव है या मैं बस एक ले रहा हूं गलत दृष्टिकोण? क्या एक अलग संरचना का उपयोग करना बेहतर होगा, जैसे स्कैला देशी कॉन्वेंट क्लास?

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

पीएस .: मैंने विशेषता के बजाय वर्ग और अमूर्त वर्ग के साथ भी प्रयास किया है लेकिन हमेशा एक ही परिणाम!

संपादित करें:

package object ga { 


    class Gene[+T](val gene: Vector[T]){ 

    def apply(idx: Int) = gene(idx) 

    override def toString() = gene.toString 

    } 

    implicit def toGene[T](a: Vector[T]) = new Gene(a) 

    type Genome = Array[Gene[Any]] 

} 

package test 

import ga._ 

object Test { 
    def main(args: Array[String]) { 
     val g = Vector(1, 3, 4) 

     val g2 = Vector("a", "b") 

     val genome1: Genome = Array(g, g2) 

     println("Genome") 

     for(gene <- genome1) println(gene.gene) 
    } 
} 

तो मैं अब लगता है कि मैं डाल दिया और विभिन्न प्रकार में डेटा पुनः प्राप्त और उन सब प्रकार के साथ उपयोग कर सकते हैं: डिडिएर Dupont द्वारा तरह सुझाव से मैं इस कोड के लिए आया था उपहार की जांच!

उत्तर

9

ऐरे इनवेरिएंट है क्योंकि आप इसमें लिख सकते हैं।

तुम क्या

val typed = new Gene[String] 
val untyped : Gene[Any] = typed // covariance would allow that 
untyped.gene(0) = new Date(...) 

इस दुर्घटना होगा (अपने उदाहरण में सरणी किसी सरणी [स्ट्रिंग] है और एक तिथि को स्वीकार नहीं करेगा) मान लीजिए। यही कारण है कि संकलक इसे रोकता है।

वहां से, यह जीन के साथ आप जो करना चाहते हैं उस पर बहुत निर्भर करता है। आप Array के बजाय एक कॉन्वेंट प्रकार का उपयोग कर सकते हैं (आप Vector पर विचार कर सकते हैं), लेकिन यह उपयोगकर्ता को सामग्री को म्यूट करने से रोक देगा, अगर यह आपके इरादे से था। आपके पास कक्षा के अंदर एक ऐरे भी हो सकती है, बशर्ते इसे private [this] घोषित किया गया हो (जो सामग्री को भी उत्परिवर्तित करने में काफी कठिन बना देगा)। यदि आप चाहते हैं कि क्लाइंट को जीन की सामग्री को म्यूटेट करने की अनुमति दी जाए, तो संभवतः जीन कॉन्वेंटेट करना संभव नहीं होगा।

+0

नहीं, मुझे इसे बदलने की जरूरत नहीं है और मैं वास्तव में वेक्टर के बारे में हालांकि। मेरी मुख्य आवश्यकता में क्लाइंट कोड अलग-अलग जीन [टी] की सरणी का प्रबंधन कर रहा है, लेकिन अभी भी संचालन पर प्रकार की बाधाओं के साथ है। मुझे पता है कि यह मुश्किल है और अभी भी मेरे पहले कदमों पर होने के कारण मैं बस बहुत कार्यात्मक, या बहुत गतिशील सोच रहा हूं, लेकिन मैं कुछ बड़ा विकसित करना चाहता हूं और यह एक आवश्यकता हो सकती है: स्वचालित मुक्केबाजी और मूल्यों का अनबॉक्सिंग। अगर आप चाहते हैं कि मैं सवाल दोबारा कर सकता हूं! –

+0

कृपया करें। आप जो करते हैं वह काम नहीं करेगा, लेकिन आपको जो चाहिए उसे नहीं जानना, और अधिक मदद करना मुश्किल है। प्रदर्शन क्या कारण है कि आप एक ऐरे चाहते हैं?ग्राहक जीन [टी] के एक विषम संग्रह के साथ क्या करने की उम्मीद है? –

+0

मेरा जवाब संपादित किया गया। कृपया इसकी समीक्षा करें क्योंकि मुझे लगता है कि आपकी मदद के लिए धन्यवाद मुझे एक समाधान मिला है। जाहिर है, मैं आपका जवाब स्वीकार करने जा रहा हूं;) –

2

gene के प्रकार को इसके प्रकार पैरामीटर में कॉन्वर्सेंट होना आवश्यक है। इसके लिए संभव है, उदाहरण के लिए, आपको एक अपरिवर्तनीय डेटा संरचना चुननी होगी। लेकिन आप scala.collection.immutable पैकेज से किसी भी डेटा संरचना का उपयोग कर सकते हैं।

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