我有一个协议(protocol)Node
:
protocol Node {
var parent: Node?
var children: [Node]
}
由类实现:
class TreeNode: Node {
var parent: Node?
var children: [Node]
}
但这会带来一个问题,即访问 TreeNode
中的父级。现在给我一个Node
,我想做 TreeNode
对他们进行具体的操作。所以我想将协议(protocol)更改为:
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]'
根据我收集到的有关此问题的信息,我需要实现一种类型删除机制来支持此架构。但在我的例子中如何做到这一点呢?
最佳答案
您可能希望节点的父节点和子节点与节点本身具有相同类型,而不仅仅是某些类型符合Node
.这将是协议(protocol)定义中的Self
:
protocol Node {
var parent: Self? { get set }
var children: [Self] { get set }
}
现在您可以定义具体类(请参阅A Swift protocol requirement that can only be satisfied by using a final class了解为什么该类需要final
):
final class TreeNode: Node {
var parent: TreeNode? = nil
var children: [TreeNode] = []
}
和
func getReversedChildren<T: Node>(node: T) -> [T] {
return node.children.reversed()
}
编译没有问题。
关于swift - 数组中的协议(protocol)和关联类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54267521/