swift - 当类型符合多个协议时,为什么不满足 Swift 协议一致性
问题描述
假设您有以下协议和类:
protocol Foo { }
protocol Bar { }
protocol Deps {
var bar: Bar { get }
}
class FooBar: Foo, Bar { }
然后你定义一个新类,它的属性同时符合Foo
和Bar
协议。
class Scope: Deps {
let bar: Foo & Bar = FooBar() // ❌ does not compile
}
尽管它看起来满足Deps
协议要求,但它不能编译。编译器提供此消息:
error: type 'Scope' does not conform to protocol 'Deps'
class Scope: Deps {
^
Protocols_Question.playground:6:7: note: candidate has non-matching type 'Bar & Foo'
但是,删除第二个协议一致性解决了编译问题:
class Scope: Deps {
let bar: Bar = FooBar() // ✅ compiles
}
这里发生了什么?直觉上,第一个示例中似乎Deps
应该满足协议一致性。
这是一个演示问题的 Swift Playground 。
解决方案
这是因为 Deps 协议要求变量 bar 符合协议 Bar。您可以将类 FooBar()(同时具有 Foo 和 Bar 协议)分配给变量 bar,因为要求 bar (至少)符合 Bar 协议。但是,您不能尝试更改变量在定义后应遵循的协议。
TL;DR - 在声明变量后,您无法更改变量的类型。
推荐阅读
- python-3.x - 当用户尝试对已经完成的线程进行操作时,我应该使用 Python 的内置 ProcessLookupError 吗?
- laravel - Livewire 数据表无法访问公共财产
- python - 如何使用 aiohttp 发送文件?
- visual-studio-code - 禁用 workbench.editor.showTabs 时,如何在未聚焦的选项卡中显示面包屑?
- ansible - ansible vault 可以加密插件配置文件中的值吗?
- r - 从按 Special_ID 分组的大型数据集中采样唯一行/Normal_ID
- android - Uno Platform Android 和 UWP:如何将文件复制到本地文件夹?
- javascript - 如何在没有npm和es6的情况下在deckgl中使用FitBounds
- swiftui - 如何在不使用 Geometry Reader 的情况下获取 safeAreaInsets
- jquery - 空气日期选择器禁用日期样式在当月无效