为何需显式声明数组类型为BinaryFloatingPoint?如何优化实现?
问题原因与优化方案
为什么原代码无法编译?
你写的扩展是针对元素类型为any BinaryFloatingPoint的数组,但let d = [2.3, 4.5]会被Swift自动推断为[Double]——这是一个具体类型的数组,和[any BinaryFloatingPoint](存在类型数组)属于不同的类型,所以编译器找不到对应的mean属性。手动声明类型是把数组转换成了存在类型容器,这才匹配上扩展,但确实冗余。
优化实现方法
改用泛型约束的扩展形式,让所有元素遵循BinaryFloatingPoint协议的数组都能自动获得该属性:
extension Array where Element: BinaryFloatingPoint { var mean: Double? { guard !isEmpty else { return nil } let sum = reduce(0.0) { ret, x in ret + Double(x) } return sum / Double(count) } } // 直接使用,无需额外类型声明 let d = [2.3, 4.5] print(d.mean!) // 输出3.4 // 其他浮点类型数组同样支持 let f: [Float] = [1.2, 3.4] print(f.mean!) // 输出2.3
优化后的优势
- 符合DRY原则,调用时不需要手动指定数组类型
- 兼容所有遵循
BinaryFloatingPoint的具体类型数组(Double、Float、CGFloat等) - 同时也支持
[any BinaryFloatingPoint]类型的数组,无需额外扩展
内容的提问来源于stack exchange,提问作者johnbakers
相关产品推荐
相关产品推荐

