我有一个简单的协议Provider
,如下所示:
protocol Provider {
func get() -> String
}
和一个以存在Provider
为字段的结构体S
:
struct S {
var provider: any Provider
}
我还有一个视图ProviderView
,如下所示:
struct ProviderView<P: Provider>: View {
let provider: P
var body: some View {
Text(provider.get())
}
}
以及类似Provider
的实现:
struct DummyProvider: Provider {
func get() -> String {
"Hello World!"
}
}
现在,当我尝试在S.provider
:中使用ProviderView
传递时,问题来了
struct ContentView: View {
let s = S(provider: DummyProvider())
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
ProviderView(provider: s.provider) // This is the erroring line.
}
}
}
出现错误:
Type 'any Provider' cannot conform to 'Provider'
现在,这是意料之中的事,正如在这里和这里的回答中出色地描述的那样。
此代码不起作用的原因是View
的body
属性在运行时是固定的,因此不允许ProviderView
在动态类型上是泛型的。
问题是,一个超薄型擦除AnyProvider
结构修复了这个问题:
struct AnyProvider: Provider {
let erased: any Provider
func get() -> String {
return erased.get()
}
}
现在ProviderView
有一个具体的类型要泛型。
但是,您可以看到AnyProvider
本身实际上只是存储一个any Provider
成员变量。AnyProvider
的大小应该仍然未知。
我认为,如果问题是any Provider
的大小在运行时未知,那么为什么使用AnyProvider
可以解决这个问题呢?毕竟,它只包含一个在运行时大小未知的字段。
所以我的问题是:为什么Swift不能合成一个类似的包装器使用any Provider
和包含单个类型为any Provider
的字段的结构有什么区别
是什么阻止Swift允许您使用any Provider
与AnyProvider
?
除了类型之外,AnyProvider
如何比any Provider
更具体
我真的很想知道我是否错过了什么。
附言:我用的是Xcode 14 Beta 3和Swift 5.7。
尝试用any Provider
声明您的ProviderView
struct ProviderView: View {
let provider: any Provider
var body: some View {
Text(provider.get())
}
}