dev*_*999 5 protocols swift opaque-types
我有一个协议
protocol doSomethingProtocol {
associatedtype someType
}
Run Code Online (Sandbox Code Playgroud)
然后我有一个正在实现这个协议的类
class doSomethingClass : doSomethingProtocol {
typealias someType = Int
}
Run Code Online (Sandbox Code Playgroud)
现在我想使用这个协议作为其他类的参考
class someClass : ObservableObject {
private var reference : doSomethingProtocol
}
Run Code Online (Sandbox Code Playgroud)
现在我不能这样做,因为doSomethingProtocol有关联类型。所以我决定使用some
class someClass : ObservableObject {
private var reference : some doSomethingProtocol
init(){
reference = doSomethingClass()
}
}
Run Code Online (Sandbox Code Playgroud)
然而这不起作用。我得到了错误Property declares an opaque return type, but has no initializer expression from which to infer an underlying type。为什么 ?我在类 init 中给它初始化表达式。
但是当我做这样的事情时
class someClass : ObservableObject {
private var reference : some doSomethingProtocol = doSomethingClass()
init(){}
}
Run Code Online (Sandbox Code Playgroud)
我没有收到任何错误消息并且它可以编译。为什么,两者有什么区别。
现在我不能这样做,因为 doSomethingProtocol 有一个关联类型。所以我决定使用
some
这就是你出错的地方。不透明 ( some) 类型解决的问题与具有关联类型的协议完全不同。不透明类型是混凝土。它是一种特定类型,在编译时已知,由函数返回。只是函数的调用者不知道它。编译器完全知道它。
var reference : some DoSomethingProtocol
Run Code Online (Sandbox Code Playgroud)
鉴于此信息,具体类型是什么reference?目前尚不清楚。的行为暗示了这一点init,但并不知道总是如此。(更重要的是,因为这是一个可以覆盖它init并分配其他类型的类。)
你想要做的事情是这样完成的:
private var reference : DoSomethingClass
Run Code Online (Sandbox Code Playgroud)
这定义了 SomeType == DoSomethingClass,并允许 DoSomethingClass 符合 DoSomethingProtocol。
如果您试图避免确定 DoSomethingClass 在这里使用的类型,那是不可能的。为了符合具有关联类型的协议,您必须提供可以在编译时确定的具体类型。
考虑到您遇到的问题,我怀疑 DoSomethingClass 的设计不正确,并且您实际上并不需要此处的 PAT(具有关联类型的协议)。您可能需要一个泛型、组合或可能的闭包。您有可能(尽管不太可能)需要一个橡皮擦。但您不需要不透明的类型。
(请将您的类型大写。在 Swift 中,类型的前导小写是非常混乱的。)
| 归档时间: |
|
| 查看次数: |
5726 次 |
| 最近记录: |