【问题标题】:Extend swift array that hold specific element type扩展包含特定元素类型的 swift 数组
【发布时间】:2015-10-05 20:21:33
【问题描述】:

我一直在尝试扩展一个包含特定类型的 swift 数组。

protocol Node {
  var nodeId: Int { get }
  var parentId: Int? { get }
  var children: [Node]  { get set }
  var level: Int { get set }
}

extension Array where Element : Node {
/**
unflatten an array of Nodes.
*/
func unflattenNodes()-> [Node] {

    func unflatten(inout parent: Node?)-> [Node] {

        var topNodes = [Node]()
        let children = self.filter{ (child: Node) in return child.parentId == parent?.nodeId ?? 0 }

        if !children.isEmpty {

            if var parent = parent {
                for var child in children {
                    child.level = parent.level + 1
                }
                parent.children = children
            }
            else {
                topNodes = children
            }

            for child in children {
                var optChild = Optional(child)
                unflatten(&optChild)
            }
        }
        return topNodes;
    }

      var optChild: Node? = nil
      return unflatten(&optChild)
 }
}

上面的代码不会被编译,因为“节点”不是“元素”的子类型,即使我正在扩展元素“节点”的数组。 如何快速存档我在这里尝试做的事情? 我正在尝试将实例方法添加到 [Node] 以展开自我。

【问题讨论】:

标签: ios swift swift2


【解决方案1】:

问题在于协议Node 不符合自身:Node 不是Node 类型(听起来很矛盾),因为协议不是具体类型,它只是一个符合类型的要求。

也就是说,您需要将代码中的每个Node 实例替换为Element,然后它应该可以工作(现在无法测试)。这是因为,您实际上并没有处理Node 类型的某个值,而是一个符合Node 类型的值(在您的情况下为Element

您的代码中还有一些其他错误,我将留给其他人来纠正,因为我没时间了。

【讨论】:

    【解决方案2】:

    好的,我已将代码插入 Playground 并发现了三个问题。第一个是Kametrixom 提到的,你需要在unflattenNodes 的任何地方使用Element 作为类型。当您解决了这个问题并在对unflatten 的调用中删除了所有parent: 时,您将得到一个错误

    parent.children = children
    error: cannot assign a value of type '[Element]' to a value of type '[Node]'
                    parent.children = children
                                      ^
    

    这是因为协议中的children属性被定义为[Node],而Swift无法将其匹配到Element的数组

    所以你需要改变协议

    protocol Node {
        var nodeId: Int { get }
        var parentId: Int? { get }
        var children: [Self]  { get set }
        //            ^^^^^^ Here
        var level: Int { get set }
    }
    

    children 属性不再是 Node 的数组,而是符合协议的任何类型的数组,在您的情况下为 Element

    【讨论】:

      【解决方案3】:

      extension Array where Element : Node 更新为extension CollectionType where Generator.Element == Node 解决了该错误。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多