swift 类型“any ProtocolName”不能符合“(ProtocolName的继承协议)”[重复]

jv4diomz  于 5个月前  发布在  Swift
关注(0)|答案(1)|浏览(35)

此问题在此处已有答案

How to define a protocol as a type for a @ObservedObject property?(6个回答)
一年前关闭。
我有一个符合ObservableObject的ProtocolName,然后我有一个符合ProtocolName的ClassName。
但是,当我尝试使用@ObservedObject serviceName:ProtocolName = ClassName时,它无法构建,并显示以下消息:“Type 'any ProtocolName' cannot conform to 'ObservableObject'”
我做错了什么,我该如何解决?
范例:

protocol ProtocolName: ObservableObject {
    let random: String
}

class ClassName: ProtocolName {
    let random: String
}

@ObservedObject serviceName: ProtocolName = ClassName()

字符串

o7jaxewo

o7jaxewo1#

当你写这样一行时:

@ObservedObject var observeMe: ProtocolName

字符串
你是说observeMe是一个盒子,可以包含任何符合ProtocolName协议的东西。
这个盒子的类型是any ProtocolName,它被称为existential
但是盒子本身不符合ProtocolName(并且推而广之也不符合ObservableObject)。盒子里面的东西符合,但是盒子本身不符合。
所以编译器会抱怨类型为any ProtocolName的存在语句不是ObservableObject
您可以使用any ProtocolName语法使该框更加明显和明确:

import SwiftUI
import Combine

protocol ProtocolName: ObservableObject {
    var someValue: Int { get }
}

class MyClass: ProtocolName {
    @Published var someValue: Int = 42
}

struct SomeStruct : View {
    @ObservedObject var observeMe: any ProtocolName = MyClass()
    
    var body: some View {
        Text("Hello.")
    }
}


你仍然会看到错误。
要解决这个问题,你的@ObservedObject必须是一个符合ProtocolName的具体类型:

import SwiftUI
import Combine

protocol ProtocolName: ObservableObject {
    var someValue: Int { get }
}

class MyClass: ProtocolName {
    @Published var someValue: Int = 42
}

struct SomeStruct : View {
    @ObservedObject var observeMe: MyClass = MyClass()
    
    var body: some View {
        Text("Hello.")
    }
}

let myView = SomeStruct()


或者,您可以向视图添加类型参数,以便在创建视图时有一个符合用于视图的协议的特定类型:

import SwiftUI
import Combine

protocol ProtocolName: ObservableObject {
    var someValue: Int { get set }
}

class MyClass: ProtocolName {
    @Published var someValue: Int = 42
}

struct SomeStruct<T : ProtocolName> : View {
    @ObservedObject var observeMe:T
    
    var body: some View {
        Text("Hello.")
        Button(action: {observeMe.someValue = 3}) {
            Text("Button")
        }
    }
}

let myView = SomeStruct(observeMe: MyClass())

相关问题