【发布时间】:2016-08-27 17:00:02
【问题描述】:
我有一个协议,它有一个带有默认参数的静态方法。我想更改实现协议的类中的默认值。基本上是在做类和超级容易做的事情。
我只有在协议没有关联类型时才有解决方案。
以下代码有效,但一旦您取消注释关联的类型声明,它就无法编译。
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()
【问题讨论】:
标签: swift protocols associated-types default-implementation