これは、あなたがそれが意味どう思うかという意味ではありません:これは特化されているプロトコルとしてBarProcessor
を扱うしようとしている
init<BarProcessor:Foo>(block:(BarProcessor)->Void) where BarProcessor.Bar == U
。しかしそれはそうではありません。 BarProcessor
は具体的なタイプです。したがって、の特定の(ただし汎用)タイプを受け入れるブロックを渡しています。 MyFoo
をそれに渡そうとしますが、それはその特定のタイプではない可能性があります。
このようにプロトコルとジェネリックを混ぜ合わせていると、プロトコルを過度に使用している可能性があります。取り除くFoo
。プロトコルは実装の詳細を隠す方法ではありません。実装の詳細を隠すツールは、アクセス制御(private
およびinternal
)です。
タイプを完全に非表示にしたい場合は、プロトコルではなくタイプ消しゴムです。例えば、(彼らは「foo」と「bar」せずに何を意味するかに物事をリネーム):
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))
}
}
ありがとうございました。私のコードがやっていたことをちょっとあいまいにしていますが、私は要点を得ています。私はとにかくしようとしていたのと同じ目標を達成しています。 – SeanCAtkinson