2016-06-05 5 views
6

निम्नलिखित काम नहीं करता है, लेकिन उम्मीद है कि मदद करता है कि आप समझते हैं कि मैं क्या मतलब है:क्या कोटलिन में डेटा क्लास होने के लिए सामान्य प्रकार की आवश्यकता होती है?

class Example<T : DataClass> 

मामले में आप को पता है कि मैं पूरा करने के लिए कोशिश कर रहा हूँ चाहते हैं, यह क्या मैं मन में था का एक उदाहरण है:

class Repository<T> where T : Entity, // Entity defines mutable property 'id' 
          T : DataClass { 

    // assume there is a map here 

    fun add(obj: T) { 
    val copy = obj.copy(id = generateID()) 
    map.put(copy.id, copy) 
    } 

} 

या क्या मैं ऐसा करने का प्रयास करने का एक बेहतर तरीका है?

उत्तर

4

मुझे यह महसूस हो रहा है कि आप वास्तव में क्या चाहते हैं कि टी स्वयं को एक नई आईडी के साथ कॉपी करने में सक्षम हो, और एक आईडी हो। यह जरूरी नहीं है कि यह एक डेटा वर्ग है। तो आप इसे परिभाषित करने के लिए बस एक इंटरफ़ेस का उपयोग कर सकते हैं।

उदाहरण के लिए:

interface CopyableWithId<out T> where T: CopyableWithId<T> { 
    fun copy(newId: Long): T 
    val id: Long 
} 

data class BarBaz(override var id: Long, var name: String): CopyableWithId<BarBaz> { 
    override fun copy(newId: Long): BarBaz = copy(id = newId) 
} 

class Repository<T> where T : CopyableWithId<T>{ 

    val map: MutableMap<Long, CopyableWithId<T>> = HashMap() 

    fun add(obj: T) { 
     val copy = obj.copy(generateID()) 
     map.put(copy.id, copy) 
    } 

    private fun generateID(): Long { 
     return 1L 
    } 
} 
1

नहीं, data कक्षाओं में टाइप सिस्टम में कोई विशिष्ट प्रतिनिधित्व नहीं है और नियमित कक्षाओं (similar question) से अलग नहीं किया जा सकता है।

हालांकि, आपको data कक्षा के तरीकों की आवश्यकता हो सकती है, जिसमें कुछ संख्याओं के घटक इंटरफ़ेस का उपयोग कर रहे हैं (वास्तव में यह data कक्षाओं पर मार्कर इंटरफ़ेस होगा)।

यहाँ दो घटकों के साथ data कक्षाओं के लिए एक उदाहरण है:

interface Data2<T1, T2> { 
    operator fun component1(): T1 
    operator fun component2(): T2 
    fun copy(t1: T1, t2: T2): Data2<T1, T2> 
} 

toString, hashCode और equals वैसे भी किसी भी प्रकार पर कहा जा सकता है।

तो बस इंटरफ़ेस के साथ अपने data वर्ग का प्रतीक:

data class Impl(val i: Int, val s: String): Data2<Int, String> 

val d: Data2<Int, String> = Impl(1, "2") 
val (c1, c2) = d 
val copy = d.copy(-1, d.component2()) 

copy समारोह पूरी तरह से टाइप-सुरक्षित नहीं है, क्योंकि Kotlin doesn't have self type (और कोई रास्ता नहीं है एक विशेष प्रकार के उप प्रकार होने के लिए इंटरफेस कार्यान्वयन की आवश्यकता होती है), लेकिन अगर आप केवल data कक्षाओं को इसके साथ चिह्नित करते हैं, तो इसे काम करना चाहिए (नीचे एक और विकल्प देखें)।

val d = myD2.copy(newValue, myD2.component2()) 

एक अन्य विकल्प Data2<T1, T2, out Self>, class Impl(...): Data2<..., Impl> के रूप में इन इंटरफेस को परिभाषित करने के लिए है, और:

एक और दोष यह है कि आप copy विधि के डिफ़ॉल्ट पैरामीटर खो देते हैं और सभी मापदंडों निर्दिष्ट से कॉल करने के लिए है है copySelf लौटें, लेकिन अगर आप Data2<SomeType, SomeType, *> के रूप में इंटरफ़ेस का उपयोग करते हैं तो यह बेहतर नहीं होगा।

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