我一直在尝试扩展一个包含特定类型的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]添加一个实例方法来解除自我。
答案 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
解决了错误。