मेरे पास एक प्रोटोकॉल है Node:

protocol Node {
   var parent: Node?
   var children: [Node]
}

जो कक्षाओं द्वारा कार्यान्वित किया जाता है:

class TreeNode: Node {
   var parent: Node?
   var children: [Node]
}

लेकिन यह एक समस्या है क्योंकि TreeNode में माता-पिता तक पहुँचने से अब मुझे एक Node मिलता है, और मैं उन पर TreeNode विशिष्ट संचालन करना चाहता हूँ। इसलिए मैं प्रोटोकॉल को इसमें बदलना चाहता हूं:

protocol Node {
   associatedtype T: Node

   var parent: T?
   var children: [T]
}

जो मुझे कक्षा को इस प्रकार परिभाषित करता है:

class TreeNode: Node {
   var parent: TreeNode?
   var children: [TreeNode]
}

महान! लेकिन एक पकड़ है। अगर मैं Node के लिए एक सहायक विधि लिखना चाहता हूं जो सरणी से संबंधित है:

func getReversedChildren<T: Node>(node: T) -> [T] {
   return node.children.reversed()
}

संकलक त्रुटि के साथ विफल रहता है: Cannot convert return expression of type 'ReversedCollection<[T.T]>' to return type '[T]'

मैं इस मुद्दे के बारे में क्या इकट्ठा कर सकता हूं, मुझे इस वास्तुकला का समर्थन करने के लिए एक टाइप-इरेज़र तंत्र प्राप्त करने की आवश्यकता है। लेकिन यह मेरे उदाहरण पर कैसे किया जा सकता है?

2
Oskar 19 जिंदा 2019, 16:18

1 उत्तर

सबसे बढ़िया उत्तर

आप शायद चाहते हैं कि किसी नोड के माता-पिता और बच्चे उसी प्रकार के हों, जो स्वयं नोड के हों, न कि केवल कुछ प्रकार के हों जो Node के अनुरूप हों। प्रोटोकॉल परिभाषा में यह Self होगा:

protocol Node {
    var parent: Self? { get set }
    var children: [Self] { get set }
}

अब आप ठोस वर्ग को परिभाषित कर सकते हैं (देखें एक स्विफ्ट प्रोटोकॉल आवश्यकता जिसे केवल अंतिम वर्ग का उपयोग करके संतुष्ट किया जा सकता है कि कक्षा को final क्यों होना चाहिए:

final class TreeNode: Node {
    var parent: TreeNode? = nil
    var children: [TreeNode] = []
}

तथा

func getReversedChildren<T: Node>(node: T) -> [T] {
    return node.children.reversed()
}

समस्याओं के बिना संकलित करता है।

3
Martin R 19 जिंदा 2019, 16:34