[英]Protocols and associated types in arrays
我有一个协议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<[TT]>' to return type '[T]'
从我可以收集的有关此问题的信息来看,我需要实现一种类型擦除机制来支持此体系结构。 但是如何在我的示例中做到这一点?
您可能希望节点的父级和子级与节点本身具有相同的类型 ,而不仅仅是与Node
某种类型。 在协议定义中将是Self
:
protocol Node {
var parent: Self? { get set }
var children: [Self] { get set }
}
现在,您可以定义具体的类(请参阅Swift协议要求,该类只能通过使用final类来满足,以了解为什么该类需要为final
):
final class TreeNode: Node {
var parent: TreeNode? = nil
var children: [TreeNode] = []
}
和
func getReversedChildren<T: Node>(node: T) -> [T] {
return node.children.reversed()
}
编译没有问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.