我有通用,我希望能够使用特定约束初始化它。约束仅用于初始化。班上的其他人都不在乎。这是一个简化的例子:
struct Generic<T> {
let compare: (T, T) -> Bool
init<T: Equatable>(data: [T]) {
let handler: (T, T) -> Bool = { $0 == $1 }
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])
同样的效果了。
我正在使用以下解决方法:我创建了一个顶级函数并删除了专门的init:
func equatableHandler<T: Equatable>(left: T, right: T) -> Bool {
return left == right
}
结构体的客户端可以使用:Generic(compareHandler: equatableHandler, data: data)
这不是使用专门的init
的“便利”,但我认为它对我的目的来说足够好。我不是创建顶级函数的粉丝,但泛型经常用于“Equatable”泛型,因此我有必要为客户端定义一次处理程序。
答案 0 :(得分:5)
问题是第一个init方法
init<T: Equatable>(data: [T])
引入了隐藏(并且完全是)的本地类型占位符T
与T
类型的占位符Generic
无关,所以它
与Array extension to remove object by value中的问题基本相同。
从Swift 2开始,你可以使用&#34;限制扩展来解决这个问题&#34;:
extension Generic where T : Equatable {
init(data: [T]) {
let handler: (T, T) -> Bool = { $0 == $1 }
compare = handler
// ...
}
}
对于Swift 1.x,唯一的解决方案可能是定义一个全局帮助器 功能
func makeGeneric<T : Equatable>(data: [T]) -> Generic<T> {
return Generic(compareHandler: { $0 == $1 }, data: data)
}
(我想不出这个功能的合理名称:)。