Swift中如何让CGPoint遵循Double类型的自定义DMPoint协议?
解决方案
方法1:通过计算属性适配类型
直接扩展CGPoint时,为协议要求的Double类型x、y提供计算属性,利用Swift的数值自动转换完成类型适配,同时实现协议要求的初始化方法:
// 你的原始协议 protocol DMPoint { var x: Double { get set } var y: Double { get set } init(x: Double, y: Double) } // 扩展CGPoint遵循DMPoint extension CGPoint: DMPoint { // 计算属性适配Double类型 var x: Double { get { Double(self.x) } set { self.x = CGFloat(newValue) } } var y: Double { get { Double(self.y) } set { self.y = CGFloat(newValue) } } // 实现协议要求的初始化方法 init(x: Double, y: Double) { self.init(x: CGFloat(x), y: CGFloat(y)) } }
这里的计算属性会在获取时将CGFloat转为Double,设置时将Double转为CGFloat,完全满足协议的类型要求,同时不修改原始协议定义。
方法2:使用关联类型让协议支持多类型
如果希望协议本身能兼容不同数值类型(比如Double、CGFloat),可以给协议添加关联类型,这样既可以让使用Double的类遵循,也能让CGPoint以CGFloat类型适配:
// 修改协议为带关联类型的版本 protocol DMPoint { associatedtype CoordinateType: BinaryFloatingPoint var x: CoordinateType { get set } var y: CoordinateType { get set } init(x: CoordinateType, y: CoordinateType) } // 让使用Double的类遵循(比如自定义的MyPoint) class MyPoint: DMPoint { var x: Double var y: Double init(x: Double, y: Double) { self.x = x self.y = y } } // 扩展CGPoint遵循DMPoint,指定关联类型为CGFloat extension CGPoint: DMPoint { typealias CoordinateType = CGFloat // CGPoint本身的x、y已经符合要求,无需额外实现 // 初始化方法也自带init(x: CGFloat, y: CGFloat),满足协议要求 }
这种方式更灵活,协议可以适配任意浮点类型,同时保留对Double类型类的支持,也能完美兼容CGPoint。
内容的提问来源于stack exchange,提问作者Albu Alex-Stefan
相关产品推荐
相关产品推荐

