web-dev-qa-db-fra.com

Comment mettre en œuvre le protocole comparable de Swift?

Comment utiliser le protocole comparable dans Swift? Dans la déclaration, il est dit que je dois implémenter les trois opérations <, <= et> =. J'ai mis tout ça en classe mais ça ne marche pas. Dois-je également avoir les trois? Parce qu'il devrait être possible de tous les déduire d'un seul.

36
Kametrixom

Le protocole Comparable étend le protocole Equatable -> implémentez les deux

Dans Apple's Reference est un exemple de Apple (dans la référence du protocole comparable), vous pouvez voir comment vous devez le faire: ne placez pas les implémentations d'opération dans la classe , mais plutôt sur la portée externe/globale. Il vous suffit également d'implémenter le < opérateur depuis Comparable protocole et == du protocole Equatable.

Exemple correct:

class Person : Comparable {
    let name : String

    init(name : String) {
        self.name = name
    }
}

func < (lhs: Person, rhs: Person) -> Bool {
    return lhs.name < rhs.name
}

func == (lhs: Person, rhs: Person) -> Bool {
    return lhs.name == rhs.name
}

let paul = Person(name: "Paul")
let otherPaul = Person(name: "Paul")
let ben = Person(name: "Ben")

paul > otherPaul  // false
paul <= ben       // false
paul == otherPaul // true
60
Kametrixom

Voici une mise à jour de la réponse de Kametrixom pour Swift:

class Person : Comparable {

    let name : String

    init(name : String) {
        self.name = name
    }    

    static func < (lhs: Person, rhs: Person) -> Bool {
        return lhs.name < rhs.name
    }

    static func == (lhs: Person, rhs: Person) -> Bool {
        return lhs.name == rhs.name
    }
}

Les instances de la classe Person peuvent alors être comparées avec les opérateurs relationnels comme suit:

let paul = Person(name: "Paul")
let otherPaul = Person(name: "Paul")
let ben = Person(name: "Ben")

print(paul > otherPaul)  // false
print(paul <= ben)       // false
print(paul == otherPaul) // true
4
Ekra

Pour implémenter le protocole Comparable de Swift, vous devez d'abord vous conformer au protocole Equatable en implémentant static func == (lhs: Self, rhs: Self) -> Bool, puis en implémentant la seule fonction requise static func < (lhs: Self, rhs: Self) -> Bool for Comparable.

Au lieu de déclarer des surcharges globales d'opérateurs, vous devez plutôt implémenter les méthodes conformes au protocole dans la structure/classe elle-même. Bien que les surcharges globales des opérateurs satisfassent à la conformité du protocole, il est déconseillé de les déclarer ainsi au lieu des méthodes statiques prévues sur la structure/classe.

Si vous regardez l'exemple de documentation, vous verrez que la même chose est affichée comme exemple de code.

J'écrirais plutôt ce qui suit:

class Person: Comparable {
    let name: String

    init(name: String) {
        self.name = name
    }

    static func < (lhs: Person, rhs: Person) -> Bool {
        return lhs.name < rhs.name
    }

    static func == (lhs: Person, rhs: Person) -> Bool {
        return lhs.name == rhs.name
    }
}

ou même séparer la conformité du protocole de la déclaration de classe comme ceci:

class Person {
    let name: String

    init(name: String) {
        self.name = name
    }
}

extension Person: Comparable {
    static func < (lhs: Person, rhs: Person) -> Bool {
        return lhs.name < rhs.name
    }

    static func == (lhs: Person, rhs: Person) -> Bool {
        return lhs.name == rhs.name
    }
}

qui serait probablement plus proche du code de niveau de production.

0
Schemetrical