考虑以下代码,我尝试在Swift中实现Haskell Data.List.concat
:
protocol Concatenable: SequenceType {
func +(lhs: Self, rhs: Self) -> Self
init()
}
extension Array: Concatenable {}
func concatenate<S: SequenceType, C: Concatenable where S.Generator.Element == C>(seq: S) -> C {
var result = C()
for elem in seq {
result = result + elem
}
return result
}
这很有效,但如果将行result = result + elem
改为result += elem
,我会收到错误&#34;&#39; C&#39;与&#39; UInt8&#39;&#34;不同。我的理解是+=
只是语法糖,而不是单独的运算符,因此result = result + elem
应该绝对等同于result += elem
。要么这个假设不正确,要么这是Swift中的一个错误。 (UInt8
来自哪里?我知道这种类型是什么,但为什么Swift编译器认为这段代码与它有关?)
答案 0 :(得分:2)
不,+=
是一个单独的运算符,因此您必须将其添加到协议定义中:
protocol Concatenable {
func +(lhs: Self, rhs: Self) -> Self
func +=(inout lhs: Self, rhs: Self)
init()
}
Swift错误消息可能会产生误导。也许编译器尝试使用已知的任何
+=
定义,例如
func +=(inout lhs: UInt8, rhs: UInt8)
将参数转换为UInt8
。
请注意,您可以使用内置库函数join()
获得类似的功能:
let foo = join([], [[1, 2], [3, 4]])
println(foo)
// [1, 2, 3, 4]