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

Swift中遵循继承协议的实例作为inout参数传参编译报错问题

错误原因
  • inout 参数要求传入变量的静态类型和参数声明类型完全一致,不支持隐式的协议向上转换。你代码中变量s的静态类型是SportsCar,而test_car的参数类型是inout Car,类型不匹配因此触发编译错误。
  • 非inout场景下支持隐式向上转换是因为参数只读,不会修改原变量的类型;但inout参数可读可写,函数内部可以给参数赋值任意遵守Car协议的实例,如果允许SportsCar类型变量传入,赋值后可能违反原变量的SportsCar类型约束,编译器为了保证类型安全直接禁止了这种隐式转换。
  • 你当前的代码还存在一个低级错误:inout参数传参时必须添加&符号,原调用写法test_car(car: s )哪怕类型匹配也会编译失败。
解决方案

方案1:修改变量静态类型

如果业务中不需要使用s的SportsCar专属属性/方法,直接把s的声明类型改为Car即可:

// 原声明:var s: SportsCar
var s: Car

调用时添加&符号:

test_car(car: &s)

方案2:临时类型转换

如果需要保留s的SportsCar类型,可以临时转换为Car类型传入函数,执行完成后再转回SportsCar:

func run() {
    print("Running Test")
    var temp: Car = s
    test_car(car: &temp)
    s = temp as! SportsCar // 已知temp原始类型为SportsCar,可安全强转
    print("Finished Test")
}

方案3:使用泛型约束(最推荐)

给test_car添加泛型约束,让它支持所有遵守Car协议的类型,不需要修改原有变量类型也不需要手动转换:

// 修改函数声明
func test_car<T: Car>(car: inout T) {
    print("Car has \(car.wheels) wheels")
    car.wheels += 1
    print("Wheel added")
    print("Car now has \(car.wheels) wheels\n")
}

调用时直接传&s即可正常运行:

test_car(car: &s)

内容的提问来源于stack exchange,提问作者Jonathan Stanley-Smith

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 23:18:00