微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

通过Non-Optional

如何解决通过Non-Optional

我有一个带有可选属性的协议。

大多数符合此协议的类型将具有匹配的可选属性。但是,一个具有相同类型和名称的非可选属性

protocol SomeProtocol {
    var foo: Int? { get }
}

struct StructA: SomeProtocol {
    let foo: Int?
}

struct StructB: SomeProtocol {
    let foo: Int // Type 'StructB' does not conform to protocol 'SomeProtocol'
}

按Xcode的“固定-是否要添加协议存根?”按钮添加属性的可选版本,但是结构现在具有无效的重复变量名称

struct StructB: SomeProtocol {
    let foo: Int
    var foo: Int? { return foo } // Invalid redeclaration of 'foo'
}

在仅{ get }的情况下,由于非可选项始终满足可选项的约束,因此我假设这将“正常工作”,类似于您可以在操作符中返回非可选项的方式。具有可选返回类型的函数。但是显然不是这样。

这对功能也一样;声明func bar() -> Int?的符合类型不满足协议的func bar() -> Int

有什么办法解决这个问题?我不想重命名变量或添加间的吸气剂。

Swift是否考虑过这种情况?不允许非可选变量满足可选协议变量的原因是什么?

解决方法

如果协议提供的默认实现返回一个可选的内容:

protocol SomeProtocol {
    var foo: Int? { get }
}

extension SomeProtocol {
    var foo: Int? { return nil }
}
然后,

符合协议的类型可以提供变量/函数的重写的非可选版本:

struct StructB: SomeProtocol {
    let foo: Int
}

我在Swift Evolution论坛上发现了这个问题:

乍一看,我认为有一条规则可以使我们满足非可选类型的协议要求,但这会导致错误。仅在进一步调查后,我才注意到必须存在默认实现,以便使用非可选版本“超出”要求。

https://forums.swift.org/t/how-does-this-rule-work-in-regard-of-ambiguity/19448

Swift小组还讨论了允许非可选类型满足可选值协议的问题:

允许非可选类型满足协议要求是否有意义,例如失败的init类型? (可能带有一些隐式的可选促销。)

是的,完全是!除了这会改变现有代码的行为的那部分之外,因此我们必须对此非常小心。这被视为[SR-522] Protocol funcs cannot have covariant returns

的一部分

可在此处的堆栈溢出中进行跟踪:

Why can't a get-only property requirement in a protocol be satisfied by a property which conforms?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。