मेरे पास एक प्रोटोकॉल है 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]'
मैं इस मुद्दे के बारे में क्या इकट्ठा कर सकता हूं, मुझे इस वास्तुकला का समर्थन करने के लिए एक टाइप-इरेज़र तंत्र प्राप्त करने की आवश्यकता है। लेकिन यह मेरे उदाहरण पर कैसे किया जा सकता है?
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()
}
समस्याओं के बिना संकलित करता है।