這並不意味着你認爲它的意思是:
init<BarProcessor:Foo>(block:(BarProcessor)->Void) where BarProcessor.Bar == U
這是試圖把BarProcessor
作爲已專門的協議。但事實並非如此。 BarProcessor
這裏是一個具體類型。所以你通過一個接受特定(但通用)類型的塊。然後,您嘗試將MyFoo
傳遞給它,這可能不是特定類型。
當你發現自己以這種方式混合協議和泛型時,你可能會濫用協議。擺脫Foo
。協議不是隱藏實現細節的一種方式。隱藏實現細節的工具是訪問控制(private
和internal
)。
如果你想完全隱藏類型,這是一個橡皮擦,而不是一個協議。例如(重命名的東西,他們的意思沒有「富」與「酒吧」):
private struct MyProcessor<T> {
func process(element: T) {}
}
// Type-erases MyProcessor
struct Processor<T> {
fileprivate let processor: MyProcessor<T>
func process(element: T) { processor.process(element: element) }
}
class Machine<U> {
private let myProcessor = MyProcessor<U>()
init(block: (Processor<U>)->Void) {
block(Processor(processor: myProcessor))
}
}
或者,如果你有,你想使個人處理器的多個內部實現,你可以使用私有協議,但關鍵是外部世界只能看到類型橡皮擦,而不是PAT。
private protocol Processing {
associatedtype Element
func process(element: Element)
}
private struct MyProcessor<T>: Processing {
func process(element: T) {}
}
struct Processor<T> {
private let _process: (T) ->()
fileprivate init<P: Processing>(_ processor: P) where P.Element == T {
_process = processor.process
}
func process(element: T) { _process(element) }
}
class Machine<U> {
private let myProcessor = MyProcessor<U>()
init(block: (Processor<U>)->Void) {
block(Processor(myProcessor))
}
}
感謝羅布,這是有道理的。我對代碼的做法仍然有點模糊,但我明白了;但是使用type-erasure可以達到我想要的目標。 – SeanCAtkinson