Swift init 中的通用约束
Swift Generic constraints in init
我有泛型,我希望能够使用特定约束对其进行初始化。约束仅用于初始化。 class 的其余部分不在乎。这是一个简化的例子:
struct Generic<T> {
let compare: (T, T) -> Bool
init<T: Equatable>(data: [T]) {
let handler: (T, T) -> Bool = { [=11=] == }
compare = handler
insert(data)
}
init(compareHandler: (T, T) -> Bool, data[T]) {
compare = self.compareHandler
insert(data)
}
}
你可以看到有两个初始化器。第二个显然工作正常。但是,在第一个中,局部类型 T
与结构的泛型类型不匹配。因此,例如,尝试插入数据时我得到 Cannot invoke 'insert' with an argument list of type '([T])'
。我是否可以将 Struct 的泛型类型专门用于初始化或特定函数?
请注意,我已经尝试 init<T where T:Equatable>(data: [T])
达到同样的效果。
更新
我正在使用以下解决方法:我创建了一个顶级函数并删除了专门的初始化:
func equatableHandler<T: Equatable>(left: T, right: T) -> Bool {
return left == right
}
该结构的客户端可以使用以下方式进行初始化:Generic(compareHandler: equatableHandler, data: data)
它不完全是使用专门 init
的 "convenience",但我想它对我的目的来说已经足够好了。我不喜欢创建顶级函数,但是泛型经常用于 "Equatable" 泛型,所以我定义一次处理程序供客户使用是有意义的。
问题是第一个init方法
init<T: Equatable>(data: [T])
引入了一个本地类型占位符 T
隐藏(并且完全
与 Generic
类型的占位符 T
无关,所以它
本质上与 Array extension to remove object by value.
中的问题相同
从 Swift 2 开始,您可以使用 "restricted extension":
来解决这个问题
extension Generic where T : Equatable {
init(data: [T]) {
let handler: (T, T) -> Bool = { [=11=] == }
compare = handler
// ...
}
}
对于Swift 1.x,唯一的解决方案可能是定义一个全局助手
函数
func makeGeneric<T : Equatable>(data: [T]) -> Generic<T> {
return Generic(compareHandler: { [=12=] == }, data: data)
}
(我想不出一个合理的函数名称 :)。
我有泛型,我希望能够使用特定约束对其进行初始化。约束仅用于初始化。 class 的其余部分不在乎。这是一个简化的例子:
struct Generic<T> {
let compare: (T, T) -> Bool
init<T: Equatable>(data: [T]) {
let handler: (T, T) -> Bool = { [=11=] == }
compare = handler
insert(data)
}
init(compareHandler: (T, T) -> Bool, data[T]) {
compare = self.compareHandler
insert(data)
}
}
你可以看到有两个初始化器。第二个显然工作正常。但是,在第一个中,局部类型 T
与结构的泛型类型不匹配。因此,例如,尝试插入数据时我得到 Cannot invoke 'insert' with an argument list of type '([T])'
。我是否可以将 Struct 的泛型类型专门用于初始化或特定函数?
请注意,我已经尝试 init<T where T:Equatable>(data: [T])
达到同样的效果。
更新
我正在使用以下解决方法:我创建了一个顶级函数并删除了专门的初始化:
func equatableHandler<T: Equatable>(left: T, right: T) -> Bool {
return left == right
}
该结构的客户端可以使用以下方式进行初始化:Generic(compareHandler: equatableHandler, data: data)
它不完全是使用专门 init
的 "convenience",但我想它对我的目的来说已经足够好了。我不喜欢创建顶级函数,但是泛型经常用于 "Equatable" 泛型,所以我定义一次处理程序供客户使用是有意义的。
问题是第一个init方法
init<T: Equatable>(data: [T])
引入了一个本地类型占位符 T
隐藏(并且完全
与 Generic
类型的占位符 T
无关,所以它
本质上与 Array extension to remove object by value.
从 Swift 2 开始,您可以使用 "restricted extension":
来解决这个问题extension Generic where T : Equatable {
init(data: [T]) {
let handler: (T, T) -> Bool = { [=11=] == }
compare = handler
// ...
}
}
对于Swift 1.x,唯一的解决方案可能是定义一个全局助手 函数
func makeGeneric<T : Equatable>(data: [T]) -> Generic<T> {
return Generic(compareHandler: { [=12=] == }, data: data)
}
(我想不出一个合理的函数名称 :)。