【问题标题】:Does swift type inference not work with function return types?快速类型推断不适用于函数返回类型吗?
【发布时间】:2022-01-14 18:06:31
【问题描述】:

Swift 类型推断不适用于函数返回类型吗?

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())

我正在操场上尝试这个。为什么上面一行有错误? 编译器不应该从let v: Bike 声明中推断出Bike 的类型吗?

【问题讨论】:

    标签: ios swift generics types type-inference


    【解决方案1】:

    问题是getVehicle返回一个可选的,你必须声明

    let v: Bike? = VehicleFactory.getVehicle()
    

    您还必须在print 行中解开v

    【讨论】:

      【解决方案2】:

      不能直接回答您的问题。 Vadian 已经回答了您的实施,但有几点说明:

      (_ vehicleType: T.Type = T.self) 毫无意义。你可以省略它。

      其次,我将简单地将 init() 添加到您的协议要求中,摆脱标识符方法,将轮数更改为计算属性:

      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"
      

      【讨论】:

      • 对。计算属性更有意义。 :)
      • 顺便说一句,这是什么语法 - { .init() } - 又是类型推断吗?编译器会在相应的类型上调用 init?
      • 您可以编写 T()、T.init() 或简单的 .init()。类型是推断出来的,因为您明确设置了结果类型。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多