我跟着common pattern by Apple(第4个回复)来解决缺乏通用协议的问题:我试图实现一个GeneratorOf<T>
/ SequenceOf<T>
- 类似的结构,可以保存任何引用实现我的ExampleType
协议的实例。由于协议使用关联类型,我不能直接使用它作为变量的类型,需要一个包装器结构。
这个工作正常,直到我遇到一个通用函数。我无法创建一个闭包来转发到这个函数,因此不能像Apple在GeneratorOf<T>
中那样完全实现我的包装器结构。
这是一个简化但不完整的例子,它在Xcode 6.1 GM 2上编译得很好但缺少通用功能:
protocol ExampleType {
typealias Element
func functionWithElement(element: Element)
func functionWithSequence<S: SequenceType where S.Generator.Element == Element>(sequence: S)
}
struct ExampleOf<T>: ExampleType {
typealias Element = T
private let _functionWithElement: (T) -> ()
// how to declare _functionWithSequence?
init<E: ExampleType where E.Element == T>(_ base: E) {
_functionWithElement = { base.functionWithElement($0) }
// how to assign _functionWithSequence?
}
func functionWithElement(element: Element) {
_functionWithElement(element)
}
func functionWithSequence<S: SequenceType where S.Generator.Element == Element>(sequence: S) {
// how to call _functionWithSequence?
}
}
这就是应该工作的方式,但在Swift中显然是不可能的。
protocol ExampleType {
typealias Element
func functionWithElement(element: Element)
func functionWithSequence<S: SequenceType where S.Generator.Element == Element>(sequence: S)
}
struct ExampleOf<T>: ExampleType {
typealias Element = T
private let _functionWithElement: (T) -> ()
private let _functionWithSequence: <S: SequenceType where S.Generator.Element == Element>((S) -> ())
// ERROR: Only syntactic function types can be generic
init<E: ExampleType where E.Element == T>(_ base: E) {
_functionWithElement = { base.functionWithElement($0) }
_functionWithSequence = { base.functionWithSequence($0) }
}
func functionWithElement(element: Element) {
_functionWithElement(element)
}
func functionWithSequence<S: SequenceType where S.Generator.Element == Element>(sequence: S) {
_functionWithSequence(sequence)
}
}
我如何解决这个限制?
如果只是在包装内,我不介意在这里和那里进行演员表。
答案 0 :(得分:0)
您所要做的就是用SequenceOf<T>
包装参数:
protocol ExampleType {
typealias Element
func functionWithElement(element: Element)
func functionWithSequence<S: SequenceType where S.Generator.Element == Element>(sequence: S)
}
struct ExampleOf<T>: ExampleType {
private let _functionWithElement: (T) -> ()
private let _functionWithSequence: (SequenceOf<T>) -> ()
init<E: ExampleType where E.Element == T>(_ base: E) {
_functionWithElement = { base.functionWithElement($0) }
_functionWithSequence = { base.functionWithSequence($0) }
}
func functionWithElement(element: T) {
_functionWithElement(element)
}
func functionWithSequence<S: SequenceType where S.Generator.Element == T>(sequence: S) {
_functionWithSequence(SequenceOf(sequence))
}
}