Protocole Equatable Swift

85

Je suivais ce tutoriel pour Swift: https://www.raywenderlich.com/125311/make-game-like-candy-crush-spritekit-swift-part-1 et suis tombé sur ce code:

func == (lhs: Cookie, rhs: Cookie) -> Bool {
    return lhs.column == rhs.column && lhs.row == rhs.row
}

J'ai écrit exactement cela, mais Xcode me donne ces erreurs:

Consecutive declarations on a line must be separated by ';'
Expected declaration operators are only allowed at global scope

J'ai trouvé ce code dans la documentation d'Apple: https://developer.apple.com/documentation/swift/equatable

Ce qui est très similaire à ce que j'ai écrit. Qu'est-ce qui ne va pas? Cela me semble être un bug. J'utilise Xcode 6 Beta 2

ÉDITER:

C'est toute ma classe Cookie:

class Cookie: Printable, Hashable {
    var column: Int
    var row: Int
    let cookieType: CookieType
    let sprite: SKSpriteNode?
    
    init(column: Int, row: Int, cookieType: CookieType) {
        self.column = column
        self.row = row
        self.cookieType = cookieType
    }
    
    var description: String {
        return "type:\(cookieType) square:(\(column),\(row))"
    }
    
    var hashValue: Int {
        return row * 10 + column
    }
    
    func ==(lhs: Cookie, rhs: Cookie) -> Bool {
        return lhs.column == rhs.column && lhs.row == rhs.row
    }
}
Addison
la source
Quel est le code avant cette déclaration? Cela fonctionne bien pour moi tout seul
Connor
J'ai ajouté toute la classe à la description
Addison
8
«Les opérateurs de déclaration ne sont autorisés qu'à une portée globale. C'est l'un des meilleurs messages d'erreur du compilateur de Swift!
mat
1
vous pouvez surcharger un opérateur dans la portée de fichier uniquement.
holex
2
Vous devez func ==(lhs: Cookie, rhs: Cookie) -> Bool {...}sortir de la classe Cookie !!
Hlung

Réponses:

145

Déplacer cette fonction

func == (lhs: Cookie, rhs: Cookie) -> Bool {
    return lhs.column == rhs.column && lhs.row == rhs.row
}

En dehors de la classe cookie. Cela a du sens de cette façon car il remplace l'opérateur == à la portée globale lorsqu'il est utilisé sur deux cookies.

Connor
la source
3
Je voudrais ajouter que sur xCode 6.3.2 et swfit 1.2, func == doit être immédiatement après la définition de la classe ou de la structure. Même l'ajout d'une simple phrase comme "var a = 1" ramènera l'erreur du compilateur.
fangmobile
2
Je n'aurais jamais pensé à le mettre en dehors de la classe! Comment ça s'appelle même? Comment le trouver sur google?
rr1g0
1
Il y a une explication sur la raison pour laquelle la surcharge d'opérateur est dans la portée globale , bien qu'un changement possible soit en cours de discussion pour laisser l'implémentation de l'opérateur être à l'intérieur du type.
32

SWIFT 2:

Comme dans Swift 2 NSObjectest déjà conforme à Equatable.Vous n'avez pas besoin de conformité au sommet, c'est comme

class Cookie: NSObject {
    ...

}

Et vous devez remplacer la isEqualméthode comme

class Cookie:NSObject{
    var column: Int
    var row: Int

    //..........

    override func isEqual(object: AnyObject?) -> Bool {
        guard let rhs = object as? Cookie else {
            return false
        }
        let lhs = self

        return lhs.column == rhs.column
    }

}

Cette isEqualméthode de temps est à l'intérieur de la classe. :)

EDIT pour SWIFT 3: modifiez cette méthode comme

override func isEqual(_ object: AnyObject?) -> Bool {
        guard let rhs = object as? Cookie else {
            return false
        }
        let lhs = self

        return lhs.column == rhs.column
    }
Anish Parajuli 웃
la source
6

faire de la classe un NSObject a résolu les problèmes équivoques pour moi ...

class Cookie: NSObject {
...
}

(obtenu le conseil des tutoriels d'apprenti iOS)

Felipe Ignacio Noriega Alcaraz
la source
1
Ce serait parce que NSObject implémente ce qui suit à la ligne 70 de NSObject swiftDoc extension NSObject : Equatable, Hashable.
Adrian Sluyters