推断一个通用参数,指定其他参数

Infer one generic parameter, specify the other(s)

我有一个 struct 在两个参数中通用,FlagDataType:

struct FlagMapper<Flag, DataType> {

    let data: DataType

    init(_ data: DataType) {
        self.data = data
    }
}

DataType 可以从初始化程序中的参数 data 推断出来。所以我想写

let mapper = FlagMapper<MyFlag>(data)

当我创建一个新的 FlagMapper 时。换句话说:我只想指定无法推断的通用参数并隐式推断另一个。

有没有办法在Swift中完成这个?

或者我是否总是必须指定两个通用参数?

let mapper = FlagMapper<MyFlag, MyDataType>(data)

最好的 Swift 必须提供的是传递元类型。

struct FlagMapper<Flag, Data> {
  let data: Data

  init(_: Flag.Type, _ data: Data) {
    self.data = data
  }
}
let mapper = FlagMapper(MyFlag.self, data)

你必须让编译器知道如何构建你的 FlagMapper<Flag, DataType> :

 let mapper = FlagMapper<MyFlag>(data)

是非法的,因为 FlagMapper 有两个通用参数,你可能会得到类似的东西:

Failed to produce diagnostic for expression; please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the project

并且由于 FlagMapper 初始值设定项是:

init(_ data: DataType)

与:

 let mapper = FlagMapper(data)

它只知道 DataTypedata 的类型,但它不知道 Flag 是什么。

所以是的你需要两个通用参数:

let mapper = FlagMapper<MyFlag, MyDataType>(data)

let mapperFlagMapper: FlagMapper<MyFlag, MyDataType> = FlagMapper(data)

或变体:

let mapperFlagMapper: FlagMapper<MyFlag, MyDataType> = .init(data)

甚至:

struct FlagMapper<Flag, DataType> {

    let data: DataType

    init(_ data: DataType, flagType: Flag.Type) {
        self.data = data
    }
}
let mapperFlagMapper: FlagMapper = .init(data, flagType: MyDataType.self)