Home > Mobile >  Swift protocol default values are not changable
Swift protocol default values are not changable

Time:03-09

I have such a protocol properties with default values. But with the current implementation if I create an instance of AssetViewAttributes with some other values for avgPrice, precision they still have the default values. How can I change them?

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"

CodePudding user response:

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

This would call the getter declared in the protocol extension, which just returns "". This is because Crypto.avgPrice has no relation to the avgPrice declared in the protocol extension. You can't "override" a member in an extension, because extensions are dispatched statically. The compiler sees that test is of type AssetViewAttributes, finds the default getter you have declared in the extension, and that's what it will call.

To fix this, you need to add avgPrice as a requirement of the protocol:

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

This causes Swift to find avgPrice declared in the protocol, and dispatches it dynamically. If the implementing class happens to implement avgPrice, that implementation will be called. If not, then the default implementation is called.

  • Related