swift - 数组中的协议(protocol)和关联类型

标签 swift generics protocols swift-protocols

我有一个协议(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/

相关文章:

具有 Float 类型的 Swift String 初始值设定项生成奇怪的值

Python - 连接到随机 IP 并尝试从服务器获得响应

generics - F# 编译器在 currying 时从首次使用泛型函数推断具体类型

java - 围绕 "same erasure"编译错误的奇怪行为

java - 推断泛型类中的参数类型,这些参数类型是所提供参数的嵌套泛型类型

sockets - FIN 数据包乱序并覆盖?

swift - 重载相等运算符 (==) 来比较 String 和 Int

ios - 第一个 RxSwift 示例失败,并显示 "Cannot invoke ' mergeLatest' 和参数列表......”

ios - 使用 Swift 从 Firebase 接收信息期间变量不是 "saving"

ios - 在 Swift 中,当方向发生时如何查看 TableView 的相同单元格?