泛型类型的函数

时间:2016-06-02 04:13:00

标签: swift generics

我有一个函数可以用这样的条件计算数组中的数字总和:

func sumOfArrayWithCondition(array: [Int], filter: (element: Int) -> Bool) -> Int {
    var result = 0
    for i in 0..<array.count where filter(element: array[i]) {
        result += array[i] 
    }
    return result 
}

现在我想让它与Int, Float, Double类型一起使用。我试过了,但没有用。

protocol Addable {
    func +(lhs: Self, rhs: Self) -> Self
}

extension Int: Addable {}
extension Double: Addable {}
extension Float: Addable {}

func sumOfArrayWithCondition<T: Addable>(array: [T], filter: (element: T) -> Bool) -> T {
    var result = 0
    for i in 0..<array.count where filter(element: array[i]) {
        result += array[i] // <-------- Error here
    }
    return result // <-------- Error here
}

但它说:

  

二元运算符'+ ='不能应用于'Int'和'T'类型的操作数

那怎么做。

任何帮助将不胜感激。感谢。

2 个答案:

答案 0 :(得分:6)

第一个问题是编译器推断变量Int的类型result,因为您没有声明类型并使用0对其进行初始化。但您需要result类型为T

首先,为了将result初始化为T类型的实例,其值为0,您需要指定Addable也是IntegerLiteralConvertibleIntDoubleFloat已经是如此。然后,您可以将result声明为类型T并从那里开始。

Rob指出,如果您希望能够使用它,还需要在协议中添加+=功能。

因此,实现您所寻找目标的最终代码是:

protocol Addable : IntegerLiteralConvertible {
    func +(lhs: Self, rhs: Self) -> Self
    func +=(inout lhs: Self, rhs: Self)
}

extension Int: Addable {}
extension Double: Addable {}
extension Float: Addable {}

func sumOfArrayWithCondition<T: Addable>(array: [T], filter: (element: T) -> Bool) -> T {
    var result:T = 0
    for i in 0..<array.count where filter(element: array[i]) {
        result += array[i]
    }
    return result
}

答案 1 :(得分:4)

正如Rob所说,结果是一个Int。但根本不需要创建该方法。您希望根据您的方法签名来调用它:

let sum = sumOfArrayWithCondition(myArray, filter: myFilter)

相反,您所要做的就是使用swift提供的现有方法:

let sum = myArray.filter(myFilter).reduce(0) { $0 + $1 }