Reputation: 9660
I have following code:
protocol Vehicle {
func start()
}
class Car: Vehicle {
func start() {
print("Start car")
}
}
class MotorCycle: Vehicle {
func start() {
print("Start MotorCycle")
}
}
let vehicles: [Vehicle] = [Car(), MotorCycle()]
func get<T: Vehicle>() -> some Vehicle {
let result = vehicles.first {
$0 === T.self
}
return result!
}
// so I should be able to do this!
let car = get<Car>().start()
Inside the get
function I want to go iterate through vehicles and return the concrete type of the Vehicle, which is either Car
or MotorCycle
. Finally, I want to call start
on the returned type. How can I achieve it?
Upvotes: 1
Views: 953
Reputation: 3885
You can not compare an instance value with a type like this: $0 === T.self
. You can use $0 is T
instead.
And, when calling a generic function, you cannot explicitly specialize a generic function. The type has to be inferred, like @Sweeper said.
Upvotes: 0
Reputation: 271420
This is how get
should be written:
func get<T: Vehicle>(_ type: T.Type) -> T? {
vehicles.first(where: { $0 is T }) as? T
}
T
s in vehicles
, so we should return an optional T
.is
to check the type in the first(where:)
closure. Then, cast to T
.<Car>
to a function in Swift. Type arguments must always be inferred. So I used a formal parameter type
to help Swift infer what T
is.Caller:
get(Car.self)?.start()
Upvotes: 3