首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关于Swift 5.7存在论的问题

关于Swift 5.7存在论的问题
EN

Stack Overflow用户
提问于 2022-07-04 20:38:44
回答 2查看 257关注 0票数 1

最近,我将一些最初使用Type的代码转换为使用新的SWIFT5.7 any存在权。但是,当尝试在已经实现的泛型类型中使用any关键字时,我会遇到一些问题。

我在Xcode 14 Beta 2上运行这个程序(它已经隐式地打开了Existential)。

下面是一个示例:

代码语言:javascript
复制
protocol Provider<Value> {
    associatedtype Value
    
    func get() -> Value
}

struct S {
    var stringProvider: any Provider<String>
}

下面是一个非常简单的结构S,它有一个成员stringProvider。我在这里使用any关键字,而不是使any Provider<String>泛化,因为我希望以后能够将stringProvider重新分配到不同的值(该值具有不同的类型)。

代码语言:javascript
复制
struct ProviderView<P: Provider>: View {
    let provider: P
    
    var body: some View {
        Text(String(describing: type(of: provider.get())))
    }
}

现在我有了一个ProviderView SwiftUI结构,它接收一个Provider并使用它进行操作。

代码语言:javascript
复制
struct DummyProvider: Provider {
    typealias Value = String
    
    func get() -> String {
        "Hello World!"
    }
}

这只是一个虚拟的Provider实现,它只返回一个字符串。

这一切都很好,当我尝试将ProviderView与存在主义的any一起使用时,问题就出现了。

代码语言:javascript
复制
struct ContentView: View {
    let s = S(stringProvider: DummyProvider())
    
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundColor(.accentColor)
            
            ProviderView(provider: s.stringProvider) // This is the erroring line
        }
    }
}

我说Type 'any Provider<String>' cannot conform to 'Provider'时出错了。

我想我知道为什么,这是因为ProviderView不能将any存在主义作为一个通用的论点。

我的问题是:有什么办法可以绕过这个问题,而不返回类型擦除?我做错什么了吗?请记住,我需要能够将S.stringProvider重新分配到不同类型的Provider

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-07-04 21:42:32

这里的问题是body需要某种特定类型,所以ProviderView需要某种特定类型(因为body依赖于该类型)。它不能在运行时改变。因此,如果要在运行时改变ProviderView,那么它就不能对其提供程序具有通用性。

这意味着ProviderView.provider需要是any Provider,而不是泛型的:

代码语言:javascript
复制
struct ProviderView: View {
    let provider: any Provider

    var body: some View {
        Text(String(describing: type(of: provider.get())))
    }
}

所以这部分是应该的。

您将遇到的问题是当前运行时还不能完全处理这一问题。,稍后您将得到一个错误:

代码语言:javascript
复制
// Runtime support for parameterized protocol types is only available in iOS 99.0.0 or newer
ProviderView(provider: s.stringProvider)

虽然我鼓励你打开一个反馈来跟踪它,但我确实希望这在以后的贝塔中得到改进。

票数 1
EN

Stack Overflow用户

发布于 2022-07-05 04:55:28

any Provider是一种存在主义,而存在物是某种类型的盒子,不符合盒子内的协议,因此你会看到错误。

如果您不热衷于拥有ProviderView泛型,您可以添加一个使用some的自定义初始化器--这表示符合协议的实际值,因此编译器很高兴。

代码语言:javascript
复制
struct ProviderView: View {
    let provider: any Provider
    
    init(provider: some Provider) {
        self.provider = provider
    }
    
    var body: some View {
        Text(String(describing: type(of: provider.get())))
    }
}

虽然有了这样一个通用视图,但是使用provider没有什么可以完成的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72861825

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档