Swift 的广义类型约束
Generalized type constraints with Swift
作为练习,我正在尝试扩展 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
.
为什么编译器不允许我这样做?我该怎么做?
(我知道我稍后应该修复事物的累加方式以及 return 类型到底是什么,但我现在被类型约束困住了。)
根据 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 { [=11=].toInt() }
let si = [1, 2, 3, 4].sum(itself)
不过,必须传递一个显式函数。 (itself)
部分当然可以用{ [=14=] }
代替。 (其他人称 itself
函数为 identity
。)
请注意,需要A -> B?
时可以传递一个A -> B
函数。
作为练习,我正在尝试扩展 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
.
为什么编译器不允许我这样做?我该怎么做?
(我知道我稍后应该修复事物的累加方式以及 return 类型到底是什么,但我现在被类型约束困住了。)
根据 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 { [=11=].toInt() }
let si = [1, 2, 3, 4].sum(itself)
不过,必须传递一个显式函数。 (itself)
部分当然可以用{ [=14=] }
代替。 (其他人称 itself
函数为 identity
。)
请注意,需要A -> B?
时可以传递一个A -> B
函数。