简体   繁体   中英

Does swift type inference not work with function return types?

Does swift type inference not work with function return types?

protocol Vehicle {
    func numberOfWheels() -> Int
}

struct Car: Vehicle {
    func numberOfWheels() -> Int {
        return 4
    }
}

struct Bike: Vehicle {
    func numberOfWheels() -> Int {
        return 2
    }
}

struct Truck: Vehicle {
    func numberOfWheels() -> Int {
        return 8
    }
}

struct VehicleFactory {
    
    static func getVehicle<T: Vehicle>(_ vehicleType: T.Type = T.self) -> T? {
        let id = identifier(for: T.self)

        switch id {
        case "Car":
            return Car() as? T
        case "Bike":
            return Bike() as? T
        default:
            return nil
        }
    }
    
    private static func identifier(for type: Any.Type) -> String {
        String(describing: type)
    }
}

let v: Bike = VehicleFactory.getVehicle() // ERROR HERE: Cannot convert value of type 'T?' to specified type 'Bike'
print(v.numberOfWheels())

I am trying this in playground. Why is there an error in above line? Shouldnt the compiler infer the type to be Bike from the let v: Bike declaration?

The problem is that getVehicle returns an optional, you have to declare

let v: Bike? = VehicleFactory.getVehicle()

Further you have to unwrap v in the print line

Not a direct answer to your question. Vadian has already answered but a few notes on your implementation:

(_ vehicleType: T.Type = T.self) is pointless. You can just omit it.

Second I would simply add init() to your protocol requirements, get rid of the identifier method, change number of wheels to a computed property:

protocol Vehicle {
    init()
    var numberOfWheels: Int { get }
}

struct Car: Vehicle {
    let numberOfWheels = 4
}

struct Bike: Vehicle {
    let numberOfWheels = 2
}

struct Truck: Vehicle {
    let numberOfWheels = 8
}

struct VehicleFactory {
    static func getVehicle<T: Vehicle>() -> T { .init() }
}

let v: Bike = VehicleFactory.getVehicle()
print(v.numberOfWheels)  // "2\n"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM