[英]Swift Generic constraints in init
I have generic and I want to be able to initialize it with specific constrains. 我有泛型,我希望能够使用特定的约束来初始化它。 The constraints are only there for initialization.
约束仅用于初始化。 The rest of the class doesn't care.
班上的其他人都不在乎。 Here is a simplified example:
这是一个简化的例子:
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)
}
}
You can see there's two initializers. 你可以看到有两个初始化器。 The second one obviously works fine.
第二个显然工作正常。 However, in the first one the local type
T
is mismatched with the struct's generic Type. 但是,在第一个中,本地类型
T
与结构的泛型类型不匹配。 So, for example, attempting to insert data I get Cannot invoke 'insert' with an argument list of type '([T])'
. 因此,例如,尝试插入我得到的数据
Cannot invoke 'insert' with an argument list of type '([T])'
。 Is it possible for me to specialize the Struct's generic type only for the initialization or a specific function? 我是否可以仅针对初始化或特定函数专门化Struct的泛型类型?
Note, I've already tried init<T where T:Equatable>(data: [T])
to the same effect. 注意,我已经尝试过
init<T where T:Equatable>(data: [T])
效果相同。
I'm using the following workaround: I create a top level function and removing the specialized init: 我正在使用以下解决方法:我创建一个顶级函数并删除专用的init:
func equatableHandler<T: Equatable>(left: T, right: T) -> Bool {
return left == right
}
Clients of the struct can initialize using: Generic(compareHandler: equatableHandler, data: data)
struct的客户端可以使用:
Generic(compareHandler: equatableHandler, data: data)
进行初始化
It's not quite the "convenience" of using a specialized init
, but I suppose it works well enough for my purposes. 它不是使用专用
init
的“便利”,但我认为它对我的目的来说足够好。 I'm not a fan of creating top-level functions, but the generic is used so often for "Equatable" generics that it makes sense for me to define the handler once for clients to use. 我不是创建顶级函数的粉丝,但泛型经常用于“Equatable”泛型,因此我为客户端定义一次处理程序是有意义的。
The problem is that the first init method 问题是第一个init方法
init<T: Equatable>(data: [T])
introduces a local type placeholder T
which hides (and is completely unrelated to) the placeholder T
of the Generic
type, so it is essentially the same problem as in Array extension to remove object by value . 引入了一个本地类型的占位符
T
,它隐藏(并且完全不相关) Generic
类型的占位符T
,因此它与Array扩展中的问题基本上是相同的问题。
As of Swift 2 you can solve that with a "restricted extension": 从Swift 2开始,你可以通过“限制扩展”来解决这个问题:
extension Generic where T : Equatable {
init(data: [T]) {
let handler: (T, T) -> Bool = { $0 == $1 }
compare = handler
// ...
}
}
For Swift 1.x the only solution is probably to define a global helper function 对于Swift 1.x,唯一的解决方案可能是定义全局辅助函数
func makeGeneric<T : Equatable>(data: [T]) -> Generic<T> {
return Generic(compareHandler: { $0 == $1 }, data: data)
}
(and I could not think of a sensible name for the function :). (我无法想到这个功能的合理名称:)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.