デフォルトのパラメーターを持つ静的メソッドを持つプロトコルがあります。プロトコルを実装するクラスのデフォルト値を変更したい。クラスやスーパーで簡単にできることを本質的にやっています。
プロトコルに関連付けられたタイプがない場合にのみ解決策があります。
次のコードは機能しますが、関連する型宣言のコメントを外すとすぐにコンパイルされません。
protocol Protocol {
// associatedtype AssociatedType
}
extension Protocol {
func sayHello(name: String = "World") {
print("Hello, \(name)!")
}
}
class Class<T>: Protocol {
typealias AssociatedType = T
func sayHello(name: String = "Stack Overflow") {
// Uncommenting the Protocol.AssociatedType causes:
// Protocol can only be used as a generic constraint because it has associated type requirements
(self as Protocol).sayHello(name)
}
}
Class<()>().sayHello()
コンパイルされない理由は理解できます:Protocol
の具体的な型がありませんAssociatedType
。
したがって、質問は「プロトコルを明示的に特化できますか?」と読むべきかもしれませんが、それに対する答えはノーだと思います。
部分的な回避策があります。しかし、それが機能するときでさえ、それはひどいです。
特に、公開されているライブラリを作成していると考えるとsayHello
、次の回避策により、公開する必要があるが役に立たない2番目のプロトコルを作成する必要があります。
回避策は次のとおりです。
protocol Parent {}
protocol Protocol: Parent {
associatedtype AssociatedType
}
extension Parent {
func sayHello(name: String = "World") {
print("Hello, \(name)!")
}
}
class Class<T>: Protocol {
typealias AssociatedType = T
func sayHello(name: String = "Stack Overflow") {
(self as Parent).sayHello(name)
}
}
Class<()>().sayHello()
しかし、私sayHello
は関連付けられた型を使用しているため、これはうまくいきません。したがって、別のプロトコルに抽出することはできません。
私が明確であることを確認するために、ここに私が望むものがあります。プロトコルのクラスを置き換えるだけです:
class Protocol<T> {
func sayHello(name: String = "World") {
print("Hello, \(name)!")
}
}
class Class<T>: Protocol<T> {
override func sayHello(name: String = "Stack Overflow") {
super.sayHello(name)
}
}
Class<()>().sayHello()