我们可以在协议扩展中使用方法参数的默认值吗?
如果可以的话,我们可以在实现该协议的结构上覆盖那些方法吗?
我正在做,但是结果出乎意料。这是为什么?谢谢!
import Foundation
protocol Datasource {
func getLetter(_ uppercased: Bool) -> String
}
extension Datasource {
func getLetter(_ uppercased: Bool = true) -> String {
return uppercased ? "B" : "b"
}
}
struct ADatasource: Datasource {
func getLetter(_ uppercased: Bool = true) -> String {
return uppercased ? "A" : "a"
}
}
let datasource: Datasource = ADatasource()
datasource.getLetter(true) // returns "A"
datasource.getLetter() // returns "B"
答案 0 :(得分:1)
老实说,不确定.getLetter()
为什么选择覆盖已实现的协议扩展。
但是,我知道有一个很好的解决方法可以实现您要执行的操作:
protocol Datasource {
func getLetter(_ uppercased: Bool) -> String
}
extension Datasource {
func getLetter() -> String {
return getLetter(true)
}
func getLetter(_ uppercased: Bool) -> String {
return uppercased ? "B" : "b"
}
}
struct ADatasource: Datasource {
func getLetter(_ uppercased: Bool) -> String {
return uppercased ? "A" : "a"
}
}
let datasource: Datasource = ADatasource()
datasource.getLetter(true) // returns "A"
datasource.getLetter() // now returns "A"
答案 1 :(得分:1)
如果我没记错的话,这是因为动态调度与静态调度有关。协议扩展中声明的方法不会动态调度。
由于没有在协议中定义没有显式参数的方法,因此将以静态方式调度该调用。并且由于您已将datasource
定义为类型Datasource
,所以将调用协议的实现而不是ADatasource
的实现。
如果删除显式类型并仅使用let datasource = ADatasource()
,它将按预期工作。