Swift的广义类型约束

时间:2015-01-28 10:56:29

标签: swift type-constraints generics swift-extensions

作为练习,我尝试在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

为什么编译器不允许我这样做?我该怎么办?

(我知道我应该稍后解决事情的加起来以及返回类型究竟是什么,但我现在仍然坚持类型约束。)

1 个答案:

答案 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?函数。