Swift 协议默认值不可更改

发布于 2025-01-12 19:02:47 字数 1080 浏览 2 评论 0原文

我有这样一个带有默认值的协议属性。但在当前的实现中,如果我使用 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"

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"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

玩世 2025-01-19 19:02:47
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,它只返回 ""。这是因为 Crypto.avgPrice 与协议扩展中声明的 avgPrice 没有关系。您无法“覆盖”扩展中的成员,因为扩展是静态调度的。编译器发现 test 的类型为 AssetViewAttributes,找到您在扩展中声明的默认 getter,这就是它将调用的内容。

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

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文