扩展包含特定元素类型的swift数组

时间:2015-10-05 20:21:33

标签: ios swift swift2

我一直在尝试扩展一个包含特定类型的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'不是'Element'的子类型,即使我正在扩展元素Array“Node”。 如何在swift中存档我想要做的事情? 我正在尝试向[Node]添加一个实例方法来解除自我。

3 个答案:

答案 0 :(得分:1)

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

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

此外,您在代码中犯了一些其他错误,我会将其留给别人纠正,因为我已经没时间了。

答案 1 :(得分:1)

是的,我已将代码插入Playground,我发现了三个问题。第一个是Kametrixom提到的那个,你需要在Element中的任何地方使用unflattenNodes作为类型。如果您已修复此问题并删除parent:调用中的所有unflatten,则会出现一个错误

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

答案 2 :(得分:1)

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