[英]Swift Generic constraints in init
我有泛型,我希望能够使用特定的约束来初始化它。 约束仅用于初始化。 班上的其他人都不在乎。 这是一个简化的例子:
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
}
struct的客户端可以使用: Generic(compareHandler: equatableHandler, data: data)
进行初始化
它不是使用专用init
的“便利”,但我认为它对我的目的来说足够好。 我不是创建顶级函数的粉丝,但泛型经常用于“Equatable”泛型,因此我为客户端定义一次处理程序是有意义的。
问题是第一个init方法
init<T: Equatable>(data: [T])
引入了一个本地类型的占位符T
,它隐藏(并且完全不相关) Generic
类型的占位符T
,因此它与Array扩展中的问题基本上是相同的问题。
从Swift 2开始,你可以通过“限制扩展”来解决这个问题:
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)
}
(我无法想到这个功能的合理名称:)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.