[英]Protocols and associated types in arrays
I have a protocol Node
: 我有一个协议
Node
:
protocol Node {
var parent: Node?
var children: [Node]
}
which is implemented by classes: 通过类实现:
class TreeNode: Node {
var parent: Node?
var children: [Node]
}
But this poses a problem as accessing the parent in TreeNode
now gives me a Node
, and I want to do TreeNode
specific operations on them. 但这带来了一个问题,因为现在访问
TreeNode
的父级会给我一个Node
,并且我想对它们执行TreeNode
特定的操作。 So I want to change the protocol to: 所以我想将协议更改为:
protocol Node {
associatedtype T: Node
var parent: T?
var children: [T]
}
Which let's me define the class as: 让我将类定义为:
class TreeNode: Node {
var parent: TreeNode?
var children: [TreeNode]
}
Great! 大! But there's a catch.
但是有一个陷阱。 If I want to write a helper method for
Node
that deals with arrays: 如果我想为
Node
编写一个处理数组的辅助方法:
func getReversedChildren<T: Node>(node: T) -> [T] {
return node.children.reversed()
}
The compiler fails with the error: Cannot convert return expression of type 'ReversedCollection<[TT]>' to return type '[T]'
编译器失败,并显示以下错误:
Cannot convert return expression of type 'ReversedCollection<[TT]>' to return type '[T]'
From what I can gather about this issue, I need to achieve a type-erasure mechanism to support this architecture. 从我可以收集的有关此问题的信息来看,我需要实现一种类型擦除机制来支持此体系结构。 But how can this be done on my example?
但是如何在我的示例中做到这一点?
You probably want the parent and children of a node to be of the same type as the node itself, not just some type conforming to Node
. 您可能希望节点的父级和子级与节点本身具有相同的类型 ,而不仅仅是与
Node
某种类型。 That would be Self
in the protocol definition: 在协议定义中将是
Self
:
protocol Node {
var parent: Self? { get set }
var children: [Self] { get set }
}
Now you can define the concrete class (see A Swift protocol requirement that can only be satisfied by using a final class for why the class needs to be final
): 现在,您可以定义具体的类(请参阅Swift协议要求,该类只能通过使用final类来满足,以了解为什么该类需要为
final
):
final class TreeNode: Node {
var parent: TreeNode? = nil
var children: [TreeNode] = []
}
and 和
func getReversedChildren<T: Node>(node: T) -> [T] {
return node.children.reversed()
}
compiles without problems. 编译没有问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.