You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 21:00:51