我可以制作一个enum
泛型(每种情况下使用不同的类型),以便使用其大小写来推断出泛型类的类型吗?
我在这里有个例子:
class Config {
let name: String
init(_ name: String) {
self.name = name
}
}
class CarConfig: Config {
static let sports = CarConfig("sports")
static let van = CarConfig("van")
}
class BikeConfig: Config {
static let road = BikeConfig("road")
static let mtb = BikeConfig("mtb")
}
enum VehicleType {
case car, bike, scooter
}
class Vehicle<C: Config> {
let type: VehicleType
let config: C
init(type: VehicleType, config: C) {
self.type = type
self.config = config
}
}
let bike = Vehicle(type: .bike, config: BikeConfig.mtb)
bike.config.name // mtb
我想做的是启动一辆这样的载具:
let bike = Vehicle(type: .bike, config: .mtb)
我希望编译器推断BikeConfig
,因此可以省略它。我希望编译器知道带有Vehicle
的{{1}}总是有一个type == VehicleType.bike
的{{1}}。
我显然必须更改我的Config
:
BikeConfig
现在创建Vehicle
class Vehicle<C: Config> {
let type: VehicleType<C>
let config: C
init(type: VehicleType<C>, config: C) {
self.type = type
self.config = config
}
}
。
不知道从这里去哪里。有什么帮助吗? :)
[UPDATE:向enum VehicleType
添加了enum VehicleType<C: Config>
大小写
答案 0 :(得分:4)
您可以将{strong> Associated Values 与enum
案例一起使用,作为所需的任何类型。
使用enum VehicleType
和case car
将CarConfig
和case bike
创建BikeConfig
作为关联类型
enum VehicleType {
case car(CarConfig)
case bike(BikeConfig)
}
现在,class Vehicle
的定义可以修改为
class Vehicle {
let type: VehicleType
init(type: VehicleType) {
self.type = type
}
}
使用创建车辆实例,
let bike = Vehicle(type: .bike(.mtb))
答案 1 :(得分:2)
您已经倒退了,您不应该根据枚举值来推断泛型类型,因为这意味着您想确定一些编译时的东西(泛型类型),其值在运行时可能是已知的(枚举的值)。
因此,我们需要使type
参数成为仅编译时的东西,即也成为类型参数。
您首先引入一个VehicleTypeProtocol
和一个struct
来为每种枚举实例实现该协议:
protocol VehicleTypeProtocol {
// this associated type creates the link between a vehicle type and a config type
associatedtype ConfigType: Config
// this is so that we can assign to Vehicle.type
static var type: VehicleType { get }
}
struct Car : VehicleTypeProtocol {
typealias ConfigType = CarConfig
static var type: VehicleType { .car }
}
struct Bike : VehicleTypeProtocol {
typealias ConfigType = BikeConfig
static var type: VehicleType { .bike }
}
struct Scooter: VehicleTypeProtocol {
typealias ConfigType = BikeConfig
static var type: VehicleType { .scooter }
}
然后可以像这样实现初始化程序:
init<T: VehicleTypeProtocol>(type: T.Type, config: C) where T.ConfigType == C {
self.type = T.type
self.config = config
}
用法:
let bike = Vehicle(type: Bike.self, config: .mtb)
但是,伙计,这令人费解...