Swift中如何实现仅需单个泛型参数的嵌套泛型类?
Swift泛型优化:实现单参数ParkingSpot类
核心方案
把Vehicle从类改为带关联类型的协议,让具体的交通工具类(Car、Bicycle)遵守该协议,这样ParkingSpot只需接收一个符合协议的类型,就能自动获取其对应的推进器类型,无需重复传入Motor这类参数。
修改后的完整代码
class Propulsion { var horsePower: Double init(horsePower: Double) { self.horsePower = horsePower } static let pedes = Propulsion(horsePower: 0.2) } class Motor: Propulsion { var range: Double init(range: Double, horsePower: Double) { self.range = range super.init(horsePower: horsePower) } static let otto = Motor(range: 1000, horsePower: 100) static let electric = Motor(range: 400, horsePower: 200) } // 1. 将Vehicle改为带关联类型的协议 protocol Vehicle { associatedtype P: Propulsion var propulsion: P { get set } } // 2. 创建基类复用初始化逻辑,避免Car、Bicycle重复编写init class BaseVehicle<P: Propulsion>: Vehicle { var propulsion: P init(propulsion: P) { self.propulsion = propulsion } } class Bicycle<P: Propulsion>: BaseVehicle<P> { var hasFrontSuspension: Bool init(hasFrontSuspension: Bool, propulsion: P) { self.hasFrontSuspension = hasFrontSuspension super.init(propulsion: propulsion) } } class Car<P: Propulsion>: BaseVehicle<P> { func rangePerHorsePower() -> Double where P: Motor { propulsion.range / propulsion.horsePower } } // 3. 定义单参数的ParkingSpot class ParkingSpot<V: Vehicle> { var vehicle: V init(vehicle: V) { self.vehicle = vehicle } func taxForRange() -> Double where V.P: Motor { vehicle.propulsion.range * 50 } }
验证使用
现在可以按照你想要的方式声明停车位:
// 无需重复传入Motor参数 var carParkingSpot: ParkingSpot<Car<Motor>> // 实例化示例 let myCar = Car(propulsion: Motor.electric) carParkingSpot = ParkingSpot(vehicle: myCar) // 调用taxForRange方法 print(carParkingSpot.taxForRange()) // 输出20000.0
原写法问题解析
- 你最初尝试的
ParkingSpot<V: Vehicle<P>>写法错误,因为Swift无法从泛型参数V中自动推断出P的类型,必须显式声明,但这样就需要传入两个参数。 - 改用关联类型后,协议
Vehicle自带了关联的P类型,ParkingSpot只需约束V遵守Vehicle协议,就能通过V.P访问到对应的推进器类型,完美实现单参数需求。
内容的提问来源于stack exchange,提问作者JackS
相关产品推荐
相关产品推荐

