我们如何创建一个通用的数组扩展,它与Swift中的Number类型相加?
发布时间:2020-12-14 05:56:33 所属栏目:百科 来源:网络整理
导读:Swift允许您创建一个Array扩展,将Integer与: extension Array { func sum() - Int { return self.map { $0 as Int }.reduce(0) { $0 + $1 } }} 现在可以用它来汇总Int [],如: [1,2,3].sum() //6 但是,我们如何制作一个通用版本来支持其他Number类型,例
Swift允许您创建一个Array扩展,将Integer与:
extension Array { func sum() -> Int { return self.map { $0 as Int }.reduce(0) { $0 + $1 } } } 现在可以用它来汇总Int [],如: [1,2,3].sum() //6 但是,我们如何制作一个通用版本来支持其他Number类型,例如Double []呢? [1.1,2.1,3.1].sum() //fails 这个问题不是如何计算数字,而是如何创建一个通用的Array Extension来实现。 越来越近 这是最接近我能够得到的,如果它帮助任何人更接近解决方案: 您可以创建一个可以满足我们所需要做的协议,即: protocol Addable { func +(lhs: Self,rhs: Self) -> Self init() } 然后扩展我们要支持的每个类型符合上述协议: extension Int : Addable { } extension Double : Addable { } 然后添加一个扩展与该约束: extension Array { func sum<T : Addable>(min:T) -> T { return self.map { $0 as T }.reduce(min) { $0 + $1 } } } 现在可以针对我们扩展以支持协议的数字,即: [1,3].sum(0) //6 [1.1,3.1].sum(0.0) //6.3 不幸的是,我没有得到它的工作,而不必提供一个参数,即: func sum<T : Addable>(x:T...) -> T? { return self.map { $0 as T }.reduce(T()) { $0 + $1 } } 修改后的方法仍然可以使用1个参数: [1,3].sum(0) //6 但无法解析方法调用它没有参数,即: [1,3].sum() //Could not find member 'sum' 为方法签名添加整数也无法解决方法: func sum<T where T : Integer,T: Addable>() -> T? { return self.map { $0 as T }.reduce(T()) { $0 + $1 } } 但希望这将有助于其他人更加接近解决方案。 一些进展 从@GabrielePetronella答案看,我们可以调用上述方法,如果我们在调用站点上明确指定类型,如: let i:Int = [1,3].sum() let d:Double = [1.1,2.2,3.3].sum()
从Swift 2开始,可以使用协议扩展来做到这一点。 (详见
The Swift Programming Language: Protocols)。
首先,Addable协议: protocol Addable: IntegerLiteralConvertible { func + (lhs: Self,rhs: Self) -> Self } extension Int : Addable {} extension Double: Addable {} // ... 接下来,扩展SequenceType以添加可添加元素的序列: extension SequenceType where Generator.Element: Addable { var sum: Generator.Element { return reduce(0,combine: +) } } 用法: let ints = [0,1,3] print(ints.sum) // Prints: "6" let doubles = [0.0,1.0,2.0,3.0] print(doubles.sum) // Prints: "6.0" (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |