使用Xcode 8 beta,swift 3第二个扩展无法编译。我不明白这是一个快速的错误还是一个已知的限制。
extension Array {
func scanl<T>(initial: T, combine:(Iterator.Element, T) -> T) -> [T] {
guard let first = self.first else { return [] }
return [initial] + Array(self.dropFirst()).scanl(initial: combine(first, initial), combine: combine)
}
}
extension Array {
func scanl<T>(combine: (Iterator.Element, T) -> T) -> [T] {
guard let first = self.first else { return [] }
return Array(self.dropFirst()).scanl(initial:first, combine:combine)// Cannot convert value of type '(Element, T) -> T' To expected argument type '(_, _) -> _'
}
}
(元素,T) - &gt; T确实是函数的类型。 所以我无法理解为什么编译器期望(,) - &gt; __ 什么是这种类型意味着“我不关心类型”
答案 0 :(得分:1)
这不是错误或限制,编译器无法在编译时确定first
在您的第二个扩展中属于T
类型{{1}不必与T
相同。在两个闭包中,编译器都知道Iterator.Element
的类型为first
,但编译器无法知道它是否也是Iterator.Element
类型。
在你的第一个扩展中,你只使用T
作为first
闭包的第一个参数,它只需要类型combine
,所以一切都很好。
但是,在第二个扩展中,您尝试将Iterator.Element
作为参数传递给期望类型为first
的参数(initial
),并且编译器无法知道{{1}确实属于T
类型(与用于调用双参数first
的{{1}}闭包使用的类型T
相同),即T
} combine
的{{1}}类型。这可以通过第二个扩展的可选绑定子句中scanl
到Iterator.Element
的尝试类型转换(self
)轻松兑换。
T
如果您构造一个扫描一个类型的数组以构造另一个类型的数组的示例,那么as?
和first
不一定必须属于同一类型的事实是显而易见的,例如< / p>
T
如果您只希望您的extension Array {
func scanl<T>(combine: (Iterator.Element, T) -> T) -> [T] {
guard let first = self.first as? T else { return [] }
return Array(self.dropFirst()).scanl(initial: first, combine: combine)
}
}
方法及其收集器生成相同类型的数组(正如正在扫描的那个),那么您不需要包含通用Iterator.Element
,但可以使用在上面的扩展程序中使用T
代替/* scant [Int] array to construct [String] array */
let foo = [1, 2, 3, 4, 5]
let bar = foo.scanl(initial: "0") { String($0) + $1 }
print(bar) // ["0", "10", "210", "3210", "43210"]
。