Swift 协议默认值不可更改
Swift protocol default values are not changable
我有这样一个带有默认值的协议属性。但是对于当前的实现,如果我使用 avgPrice
、precision
的一些其他值创建 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
无关。您不能“覆盖”扩展中的成员,因为扩展是静态分派的。编译器看到 test
是 AssetViewAttributes
类型,找到您在扩展中声明的默认 getter,这就是它会调用的。
要解决此问题,您需要添加 avgPrice
作为协议的要求:
protocol AssetViewAttributes {
...
var avgPrice: String { get }
}
这会导致 Swift 找到协议中声明的 avgPrice
,并 动态地 调度它。如果实现 class 碰巧实现了 avgPrice
,则将调用该实现。如果没有,则调用默认实现。
我有这样一个带有默认值的协议属性。但是对于当前的实现,如果我使用 avgPrice
、precision
的一些其他值创建 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
无关。您不能“覆盖”扩展中的成员,因为扩展是静态分派的。编译器看到 test
是 AssetViewAttributes
类型,找到您在扩展中声明的默认 getter,这就是它会调用的。
要解决此问题,您需要添加 avgPrice
作为协议的要求:
protocol AssetViewAttributes {
...
var avgPrice: String { get }
}
这会导致 Swift 找到协议中声明的 avgPrice
,并 动态地 调度它。如果实现 class 碰巧实现了 avgPrice
,则将调用该实现。如果没有,则调用默认实现。