Swift中如何声明可接受Car或Bike两种类型的常量
解决方案
1. 泛型实现(最简洁高效)
既然Car和Bike结构完全一致,泛型是改动最小的方案,无需额外定义协议或枚举:
修改VehicleDetailsView为泛型视图:
struct VehicleDetailsView<Vehicle>: View where Vehicle: Identifiable { let vehicle: Vehicle var body: some View { // 直接访问共同属性即可,比如vehicle.name、vehicle.price VStack(alignment: .leading) { Text(vehicle.name) Text("¥\(vehicle.price)") } } }
调用时Swift会自动推断类型,无需额外修改VehiclesView的代码:
if vehiclesSort == "Cars" { ForEach(cars) { car in VehicleDetailsView(vehicle: car) // 自动识别为Car类型 } } else if vehiclesSort == "Bikes" { ForEach(bikes) { bike in VehicleDetailsView(vehicle: bike) // 自动识别为Bike类型 } }
2. 联合类型(Swift 5.7+,最贴近你的理想写法)
Swift 5.7及以上版本支持直接用Car | Bike声明联合类型,完全匹配你想要的OR效果:
struct VehicleDetailsView: View { let vehicle: Car | Bike var body: some View { // 因为结构一致,可直接访问共同属性,无需类型判断 VStack(alignment: .leading) { Text(vehicle.name) Text("¥\(vehicle.price)") } // 若需区分类型做特殊处理,可使用switch: // switch vehicle { // case let car as Car: Text("Car: \(car.name)") // case let bike as Bike: Text("Bike: \(bike.name)") // } } }
这种写法无需额外定义任何结构,直接满足你对let vehicle: Car OR Bike的需求。
3. 多初始化器方案
如果不想用泛型或联合类型,还可以给视图添加两个初始化器,分别接收Car和Bike:
struct VehicleDetailsView: View { private let name: String private let price: Double // 接收Car的初始化器 init(vehicle: Car) { self.name = vehicle.name self.price = vehicle.price } // 接收Bike的初始化器 init(vehicle: Bike) { self.name = vehicle.name self.price = vehicle.price } var body: some View { VStack(alignment: .leading) { Text(name) Text("¥\(price)") } } }
外部调用时,传Car或Bike都能正常初始化视图,避免复制整个视图代码。
内容的提问来源于stack exchange,提问作者Alexnnd
相关产品推荐
相关产品推荐

