繁体   English   中英

数组中的协议和相关类型

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM