You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GetListItem类不遵循EveryUserDocument协议的原因及解决方法咨询

报错原因及解决办法

报错原因

1. 数组类型不匹配

协议EveryUserDocument明确要求relations的类型为[EveryUserDocumentRelation],但GetListItem中定义的relations是[GetListItemRelation]。尽管GetListItemRelation遵守了EveryUserDocumentRelation协议,但Swift中具体类型数组与协议类型数组属于不同类型,无法直接满足协议的精确类型要求。

2. 未完全实现Equatable协议

EveryUserDocument继承了Equatable协议,而GetListItem是继承自NSObject的类:

  • NSObject默认的==运算符是基于对象引用的相等判断,不符合自定义类基于属性的相等需求;
  • Swift不会为继承自NSObject的类自动合成Equatable的实现,必须手动提供==运算符的自定义实现,否则编译器会判定未遵守协议。

解决办法

方法一:调整数组类型为协议类型并实现Equatable

将GetListItem的relations类型改为协议类型数组,同时手动实现Equatable协议:

public class GetListItem: NSObject, Codable, EveryUserDocument {
    public let id: Int
    public let relations: [EveryUserDocumentRelation] // 修改为协议类型数组
    
    enum CodingKeys: String, CodingKey {
        case id
        case relations
    }
    
    // 自定义Equatable实现
    public static func == (lhs: GetListItem, rhs: GetListItem) -> Bool {
        lhs.id == rhs.id && 
        lhs.relations.elementsEqual(rhs.relations) {
            $0.id == $1.id && $0.objectClass == $1.objectClass
        }
    }
}

public class GetListItemRelation: NSObject, Codable, EveryUserDocumentRelation {
    public let id: Int
    public let objectClass: String
    
    enum CodingKeys: String, CodingKey {
        case id
        case objectClass
    }
}

protocol EveryUserDocument: Equatable {
    var id: Int { get }
    var relations: [EveryUserDocumentRelation] { get }
}

protocol EveryUserDocumentRelation {
    var id: Int { get }
    var objectClass: String { get }
}

如果希望关系类型也支持相等判断,可以让EveryUserDocumentRelation继承Equatable,并在GetListItemRelation中实现==:

protocol EveryUserDocumentRelation: Equatable {
    var id: Int { get }
    var objectClass: String { get }
}

public class GetListItemRelation: NSObject, Codable, EveryUserDocumentRelation {
    public let id: Int
    public let objectClass: String
    
    enum CodingKeys: String, CodingKey {
        case id
        case objectClass
    }
    
    public static func == (lhs: GetListItemRelation, rhs: GetListItemRelation) -> Bool {
        lhs.id == rhs.id && lhs.objectClass == rhs.objectClass
    }
}

此时GetListItem的==可以简化为:

public static func == (lhs: GetListItem, rhs: GetListItem) -> Bool {
    lhs.id == rhs.id && lhs.relations.elementsEqual(rhs.relations)
}

方法二:使用关联类型实现灵活的类型匹配

修改EveryUserDocument协议,通过关联类型允许使用符合协议的具体类型数组:

protocol EveryUserDocument: Equatable {
    associatedtype RelationType: EveryUserDocumentRelation
    var id: Int { get }
    var relations: [RelationType] { get }
}

public class GetListItem: NSObject, Codable, EveryUserDocument {
    public let id: Int
    public let relations: [GetListItemRelation]
    
    enum CodingKeys: String, CodingKey {
        case id
        case relations
    }
    
    public static func == (lhs: GetListItem, rhs: GetListItem) -> Bool {
        lhs.id == rhs.id && lhs.relations == rhs.relations
    }
}

public class GetListItemRelation: NSObject, Codable, EveryUserDocumentRelation, Equatable {
    public let id: Int
    public let objectClass: String
    
    enum CodingKeys: String, CodingKey {
        case id
        case objectClass
    }
    
    public static func == (lhs: GetListItemRelation, rhs: GetListItemRelation) -> Bool {
        lhs.id == rhs.id && lhs.objectClass == rhs.objectClass
    }
}

protocol EveryUserDocumentRelation {
    var id: Int { get }
    var objectClass: String { get }
}

这种方式保留了具体类型数组的类型安全,同时满足协议要求,适用于需要针对不同文档类型使用不同关系类型的场景。


内容的提问来源于stack exchange,提问作者Lavrin Pristazh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 04:35:58