Swift 未定义属性列表的可均衡协议实现?

Swift 未定义属性列表的可均衡协议实现?,swift,reflection,compare,mirror,equatable,Swift,Reflection,Compare,Mirror,Equatable,我有一个带有Equatable协议实现的类。我知道这个类的两个对象是相等的,如果它们的所有内部变量都相等。对象可能包含数组。目前,我硬编码每个值对比较,这是不灵活的 是否有方法通过迭代属性列表来实现这种比较?例如镜像反射?假设我们有一个struct Person 现在,您可以在其中遵循Equalable协议,如下所示: extension Person: Equatable { public static func == (lhs: Person, rhs: Person) ->

我有一个带有Equatable协议实现的类。我知道这个类的两个对象是相等的,如果它们的所有内部变量都相等。对象可能包含数组。目前,我硬编码每个值对比较,这是不灵活的

是否有方法通过迭代属性列表来实现这种比较?例如镜像反射?

假设我们有一个struct Person

现在,您可以在其中遵循Equalable协议,如下所示:

extension Person: Equatable {
    public static func == (lhs: Person, rhs: Person) -> Bool {
        let children1 = Mirror(reflecting: lhs).children
        let children2 = Mirror(reflecting: rhs).children

        for child1 in children1 {
            let value1 = child1.value
            if let value2 = children2.first(where: { $0.label == child1.label })?.value {
                if String(describing: value1) != String(describing: value2) {
                    return false
                }
            } else {
                return false
            }
        }
        return true
    }
}
在上面的代码中,我比较了value1和value2的字符串值。这并不是正确的做法。但我不得不这么做,因为value1和value2是任何类型的,因此无法直接进行比较。因此,该解决方案可能不适用于Person内部的自定义类型

如果您不想单独比较所有属性,这只是一种解决方法

用法:


如果您不知道对象中符合等式的属性,会发生什么情况。请同时指定场景。列表很大,尚未完成。所以,否则每次删除或添加新属性时,我都需要重写==运算符,如果Person包含var数据:[PersonData],那么该怎么办?PersonData通过相同的方式实现equalable?我尝试用一个元素创建[PersonData],但这些元素包含不同的内部数据,您的代码说两个人是平等的
extension Person: Equatable {
    public static func == (lhs: Person, rhs: Person) -> Bool {
        let children1 = Mirror(reflecting: lhs).children
        let children2 = Mirror(reflecting: rhs).children

        for child1 in children1 {
            let value1 = child1.value
            if let value2 = children2.first(where: { $0.label == child1.label })?.value {
                if String(describing: value1) != String(describing: value2) {
                    return false
                }
            } else {
                return false
            }
        }
        return true
    }
}
let p1 = Person(name: "Name1", age: 10, designation: nil)
let p2 = Person(name: "Name1", age: 10, designation: "SE")
print(p1 == p2)