Swift中如何让Int遵循BinaryFloatingPoint或Double/CGFloat遵循BinaryInteger?
核心问题说明
你不可能让Int遵循BinaryFloatingPoint协议,也不可能让Double/CGFloat遵循BinaryInteger协议,原因有两个:
- 这两个协议是互斥的,分别对应整数类型和浮点类型的特性,没有任何内置数值类型会同时遵守这两个协议,你给泛型
T加&的组合约束,本质是要求入参同时满足整数和浮点的特性,本身就不存在符合要求的入参类型,调用必然报错。 - Swift不允许开发者在模块外修改标准库类型的协议遵从性,即便你强行写扩展声明遵守协议,也需要实现对应协议的所有要求,这类实现完全不符合
Int/Double本身的设计逻辑,没有实际使用价值。
可行解决方案
用Swift的函数重载特性,分别针对整数和浮点类型写两个同名函数,各自匹配对应的入参类型即可,代码如下:
import UIKit // 用到CGFloat需要导入UIKit或者CoreGraphics // 适配整数类型入参 func test<T: BinaryInteger>(value1: T, value2: T) { let someWork = value1 + value2 let intValue: Int = Int(someWork) let doubleValue: Double = Double(someWork) let cgfloatValue: CGFloat = CGFloat(someWork) print(intValue, doubleValue, cgfloatValue) } // 适配浮点类型入参 func test<T: BinaryFloatingPoint>(value1: T, value2: T) { let someWork = value1 + value2 let intValue: Int = Int(someWork) let doubleValue: Double = Double(someWork) let cgfloatValue: CGFloat = CGFloat(someWork) print(intValue, doubleValue, cgfloatValue) }
调用验证
你给出的两个使用场景都可以正常运行:
// 场景1:Int入参 let testValue1: Int = 2 test(value1: testValue1, value2: testValue1) // 输出 4 4.0 4.0 // 场景2:Double入参 let testValue2: Double = 2.0 test(value1: testValue2, value2: testValue2) // 输出4 4.0 4.0
如果你不想写重复的函数逻辑,可以把类型转换后的公共处理逻辑抽成单独的公共函数,两个重载只负责类型转换部分即可,进一步减少冗余代码。
内容的提问来源于stack exchange,提问作者swiftPunk
相关产品推荐
相关产品推荐

