我有一个协议,它有一个带有默认参数的静态方法。我想更改实现协议的类中的默认值。本质上是在做类和超级容易做的事情。
当协议没有关联类型时,我只有一个解决方案。
以下代码有效,但一旦您取消注释关联的类型声明,它就不会编译。
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
公开的库时,因此以下解决方法迫使我拥有第二个协议,该协议必须是公开的,但没有用。
这是解决方法:
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()