我有一个协议plt.xticks(lpos,location_withmax_no_of_companies.index, rotation=90)
:
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()
}
从我可以收集的有关此问题的信息来看,我需要实现一种类型擦除机制来支持此体系结构。但是如何在我的示例中做到这一点?
答案 0 :(得分:3)
您可能希望节点的父级和子级与节点本身具有相同的类型 ,而不仅仅是符合Node
的 some 类型。在协议定义中应为Self
:
protocol Node {
var parent: Self? { get set }
var children: [Self] { get set }
}
现在,您可以定义具体的类(有关为什么需要将类设为final
的信息,请参见A Swift protocol requirement that can only be satisfied by using a final class)
final class TreeNode: Node {
var parent: TreeNode? = nil
var children: [TreeNode] = []
}
和
func getReversedChildren<T: Node>(node: T) -> [T] {
return node.children.reversed()
}
编译没有问题。