Type 'CLLocationCoordinate2D' does not conform to protocol 'Hashable'

Bonjour à  tous


 


J'ai ce message d'erreur lorsque je tente de créer un dictionnaire comme ceci :


var tests = [CLLocationCoordinate2D:String]()


 


Alors vous me direz, si je définis la String comme clé, je n'ai plus ce problème, mais ça ne m'arrange pas...


 


J'ai trouvé une explication dans le livre d'Apple sur le Swift et quelques liens sur Google mais je peine à  comprendre vraiment ce que hashable et equatable protocol signifient.


 


Auriez-vous une explication claire à  ce sujet et me dire s'il existe un moyen de rendre conforme mon tableau ?


J'ai regardé du côté des extensions à  CLLocationCoordinate2D mais sans succès...


 


Merci


Réponses

  • CéroceCéroce Membre, Modérateur

    Je ne connais pas assez Swift pour te dire comment faire. Mais l'explication est assez simple: les dictionnaires sont implémentés sous forme d'une table de hachage. Il faut donc que la clef soit hachable, ce qui ne semble pas le cas de CLLocationCoordinate.


  • LarmeLarme Membre

    Bon, parmi les trucs un peu bizarre pour garder ta structure: Clé: Coordonnées " Valeur: String, en se basant sur les possibilités de CocoaTouch:


    NSValue peut transformer des CLLocationCoordinate qui devraient dont être hashable.


    Utiliser un dictionnaire comme clé, car au final, des coordonnées sont juste 2 double, voire un truc bâtard de type String "latitude,longitude", avec donc en type de possibilité, en Objective-C like:



    @{
    @{
    @lat:@(latInDouble),
    @long:@(longInDouble)
    }: StringValue
    }

    ou



    @{@lat,long:StringValue}
  • FKDEVFKDEV Membre

    La solution logique serait d'implémenter le protocole hashtable pour CLLocationCoordinate2D dans une extension.

  • FKDEVFKDEV Membre
    juin 2016 modifié #5


    import UIKit
    import CoreLocation

    //CLLocationCoordinate2D Equatable
    public func ==(lhs: CLLocationCoordinate2D, rhs: CLLocationCoordinate2D) -> Bool {
    return fabs(lhs.longitude - rhs.longitude) < Double(DBL_EPSILON) && fabs(lhs.latitude - rhs.latitude) < Double(DBL_EPSILON)
    }

    extension CLLocationCoordinate2D : Hashable
    {

    public var hashValue: Int {
    get {
    return Int(Int(Float(self.latitude)) << 32)|Int(Float(self.longitude))
    }
    }

    }


    var dico = [CLLocationCoordinate2D:String]()

    dico[CLLocationCoordinate2DMake(48.864, 2.371)] = "Bataclan"


    Bon il faudra peut-être revoir la fonction Hash car elle ne fonctionne qu'en 64 bits. Et le passage de Double à  Float induit une perte de précision.


    Une autre fonction hash pourrait consister à  convertir les deux coordonnées en string et à  utiliser la fonction hash du type String.


Connectez-vous ou Inscrivez-vous pour répondre.