Swift中结构体无法自动合成Equatable实现的问题
为什么LocationInfo必须手动实现Equatable的==方法?
问题的核心出在你结构体里的 devices: [any DeviceInfoProtocol] 属性上:
- Swift编译器无法为包含存在类型数组的结构体自动合成Equatable实现。哪怕
DeviceInfoProtocol本身遵循Equatable,any DeviceInfoProtocol作为存在类型,编译器没办法自动判断两个数组里的元素是否属于同一具体类型,同时值相等——这种动态类型的比较逻辑,自动合成的代码处理不了。 - 你其他的属性都是符合自动合成要求的:可选类型(比如
gatewayId)、数组(比如rooms)、自定义的Equatable/Hashable类型(比如UserRoleModel),这些都能被编译器自动处理,唯独这个存在类型数组拖了后腿,导致整个结构体无法自动满足Equatable协议。
要解决这个问题,你必须手动实现==方法:
- 先逐一比较除了
devices之外的所有属性,直接用普通的相等判断即可; - 专门处理
devices数组:遍历两个数组的元素,先确认元素的具体类型完全一致,再比较它们的值是否相等。
举个实现示例:
struct LocationInfo: Equatable { // ... 你的属性定义 static func == (lhs: LocationInfo, rhs: LocationInfo) -> Bool { // 比较其他所有属性 guard lhs.gatewayId == rhs.gatewayId, lhs.gatewaySerialNumber == rhs.gatewaySerialNumber, lhs.locationId == rhs.locationId, lhs.locationName == rhs.locationName, lhs.role == rhs.role, lhs.rooms == rhs.rooms, lhs.gateways == rhs.gateways, lhs.devicesGroups == rhs.devicesGroups, lhs.membershipId == rhs.membershipId, lhs.partners == rhs.partners, lhs.scripts == rhs.scripts else { return false } // 处理devices数组的比较 guard lhs.devices.count == rhs.devices.count else { return false } for (lhsDevice, rhsDevice) in zip(lhs.devices, rhs.devices) { // 先检查类型是否相同,再比较值 guard type(of: lhsDevice) == type(of: rhsDevice), lhsDevice as? any Equatable == rhsDevice as? any Equatable else { return false } } return true } }
如果你的DeviceInfoProtocol本身就继承了Equatable,还可以简化devices的比较逻辑:
protocol DeviceInfoProtocol: Equatable { // ... 协议内容 } // 在LocationInfo的==方法中: for (lhsDevice, rhsDevice) in zip(lhs.devices, rhs.devices) { guard type(of: lhsDevice) == type(of: rhsDevice), lhsDevice == rhsDevice else { return false } }
内容的提问来源于stack exchange,提问作者Anton Tropashko
相关产品推荐
相关产品推荐

