如何使用 SwiftUI 中的扩展将 Hashable 协议添加到 CLLocationCoordinate2D

How to add the Hashable protocol to CLLocationCoordinate2D using an extension in SwiftUI

所以我有一个自定义结构,其中一个 属性 是字符串类型,另一个是 CLLocationCoordinate2D 类型。显然,String 符合 Hashable,如果我可以扩展 CLLocationCoordinate2D 以符合 Hashable,我的自定义结构也将是 Hashable。这是我扩展 CLLocationCoordinate2D 的尝试:

extension CLLocationCoordinate2D {
    static func == (lhs: Self, rhs: Self) -> Bool {
        return lhs.latitude == rhs.latitude && lhs.longitude == rhs.longitude
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(self.latitude) //wasn't entirely sure what to put for the combine parameter but I saw similar things online
    }
}

您需要明确声明Hashable

extension CLLocationCoordinate2D: Hashable {
    public static func == (lhs: Self, rhs: Self) -> Bool {
        return lhs.latitude == rhs.latitude && lhs.longitude == rhs.longitude
    }
    
    public func hash(into hasher: inout Hasher) {
        hasher.combine(latitude)
        hasher.combine(longitude)
    }
}

CoreLocation 和 MapKit 尚未正确 Swifified。我建议为他们重用功能。

extension CLLocationCoordinate2D: HashableSynthesizable { }
extension MKCoordinateRegion: HashableSynthesizable { }
extension MKCoordinateSpan: HashableSynthesizable { }
/// A type whose `Hashable` conformance could be auto-synthesized,
/// but either the API provider forgot, or more likely,
/// the API is written in Objective-C, and hasn't been modernized.
public protocol HashableSynthesizable: Hashable { }

public extension HashableSynthesizable {
  static func == (hashable0: Self, hashable1: Self) -> Bool {
    zip(hashable0.hashables, hashable1.hashables).allSatisfy(==)
  }

  func hash(into hasher: inout Hasher) {
    hashables.forEach { hasher.combine([=11=]) }
  }
}

private extension HashableSynthesizable {
  var hashables: [AnyHashable] {
    Mirror(reflecting: self).children
      .compactMap { [=11=].value as? AnyHashable }
  }
}