作为练习,我尝试在Swift中扩展Array
以添加sum()
成员函数。这应该是类型安全的,我希望只有在数组包含可以加起来的元素时才调用sum()
进行编译。
我尝试了一些类似的变体:
extension Array {
func sum<U : _IntegerArithmeticType where U == T>() -> Int {
var acc = 0
for elem in self {
acc += elem as Int
}
return acc
}
}
这个想法是说,“好吧,这是一个通用函数,泛型类型必须类似于Int
,并且必须与T
相同,元素的类型的数组“。但编译器抱怨:“相同类型的要求使通用参数U和T等效”。这是正确的,他们应该是附加的约束T : _IntegerArithmeticType
。
为什么编译器不允许我这样做?我该怎么办?
(我知道我应该稍后解决事情的加起来以及返回类型究竟是什么,但我现在仍然坚持类型约束。)
答案 0 :(得分:3)
根据Martin R的评论,这目前无法实现。我在这种特殊情况下想要使用的东西是明确传递T -> Int
转换函数:
extension Array {
func sum(toInt: T -> Int?) -> Int {
var acc = 0
for elem in self {
if let i = toInt(elem) {
acc += i
}
}
return acc
}
}
然后我可以写这样的东西:
func itself<T>(t: T) -> T {
return t
}
let ss = ["1", "2", "3", "4", "five"].sum { $0.toInt() }
let si = [1, 2, 3, 4].sum(itself)
但是必须传递显式函数。 (itself)
部分当然可以由{ $0 }
替换。 (其他人称之为itself
函数identity
。)
请注意,当需要A -> B
时,可以传递A -> B?
函数。