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.