Swift 协议默认值不可更改

Swift protocol default values are not changable

我有这样一个带有默认值的协议属性。但是对于当前的实现,如果我使用 avgPriceprecision 的一些其他值创建 AssetViewAttributes 的实例,它们仍然具有默认值。我该如何更改它们?

struct Crypto: AssetViewAttribures {
    let name: String
    let logo: URL
    let symbol: String
    let avgPrice: String
    let precision: Int
}

struct Commodity: AssetViewAttribures {
    let name: String
    let logo: URL
    let symbol: String
    let avgPrice: String
    let precision: Int
}

struct Fiat: AssetViewAttribures {
    let name: String
    let logo: URL
    let symbol: String
}

protocol AssetViewAttribures {
    var name: String { get }
    var logo: URL { get }
    var symbol: String { get }
}

extension AssetViewAttribures {
    var avgPrice: String { get { return "" } set {} }
    var precision: Int { get{ return 0 } set{} }
}

var type1: AssetViewAttribures = Crypto(name: "name", logo: URL(string: "https://pixabay.com/de/illustrations/online-maus-web-internet-weltweit-523234/")!, symbol: "symbol", avgPrice: "123", precision: 2)

type1.avgPrice // "" instead of "123"
var type1: AssetViewAttribures = Crypto(name: "name", logo: URL(string: "https://pixabay.com/de/illustrations/online-maus-web-internet-weltweit-523234/")!, symbol: "symbol", avgPrice: "123", precision: 2)

type1.avgPrice

这将调用协议扩展中声明的 getter,它只是 returns ""。这是因为 Crypto.avgPrice 与协议扩展中声明的 avgPrice 无关。您不能“覆盖”扩展中的成员,因为扩展是静态分派的。编译器看到 testAssetViewAttributes 类型,找到您在扩展中声明的默认 getter,这就是它会调用的。

要解决此问题,您需要添加 avgPrice 作为协议的要求:

protocol AssetViewAttributes {
    ...
    var avgPrice: String { get }
}

这会导致 Swift 找到协议中声明的 avgPrice,并 动态地 调度它。如果实现 class 碰巧实现了 avgPrice,则将调用该实现。如果没有,则调用默认实现。