Protocolo Swift Equatable

85

Eu estava seguindo este tutorial para Swift: https://www.raywenderlich.com/125311/make-game-like-candy-crush-spritekit-swift-part-1 e me deparei com este código:

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

Escrevi exatamente isso, mas o Xcode está apresentando estes erros:

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

Encontrei este código na documentação da apple: https://developer.apple.com/documentation/swift/equatable

Que é muito semelhante ao que escrevi. O que há de errado? Isso parece um bug para mim. Estou usando o Xcode 6 Beta 2

EDITAR:

Esta é toda a minha 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
fonte
Qual é o código antes dessa declaração? Funciona bem para mim por si só
Connor
Eu adicionei a classe inteira à descrição
Addison
8
"Operadores de declaração só são permitidos em escopo global" Muito claro. Esta é uma das melhores mensagens de erro do compilador do Swift!
matt
1
você pode sobrecarregar um operador apenas no escopo do arquivo .
holex
2
Você precisa sair func ==(lhs: Cookie, rhs: Cookie) -> Bool {...}da classe Cookie !!
Hlung

Respostas:

145

Mova esta função

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

Fora da classe de biscoitos. Faz sentido dessa forma, pois ele está substituindo o operador == no escopo global quando é usado em dois Cookies.

Connor
fonte
3
Eu gostaria de adicionar que no xCode 6.3.2 e swfit 1.2, func == deve estar imediatamente após a definição da classe ou estrutura. Mesmo adicionar uma frase simples como "var a = 1" trará de volta o erro do compilador.
fangmobile de
2
Eu nunca teria pensado em colocá-lo fora da classe! Como isso se chama? Como faço para encontrá-lo no google?
rr1g0
1
uma explicação sobre por que a sobrecarga do operador está no escopo global , embora uma possível mudança esteja sendo discutida para permitir que a implementação do operador esteja dentro do tipo.
32

SWIFT 2:

Como no swift 2 NSObjectjá está em conformidade com Equatable. Você não precisa de conformidade no topo, então é como

class Cookie: NSObject {
    ...

}

E você precisa substituir o isEqualmétodo como

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
    }

}

Este isEqualmétodo de tempo está dentro da classe. :)

EDIT para SWIFT 3: altere este método como

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 웃
fonte
6

fazer da classe um NSObject resolveu os problemas equacionáveis ​​para mim ...

class Cookie: NSObject {
...
}

(recebi a dica dos tutoriais de aprendizes de iOS)

Felipe Ignacio Noriega Alcaraz
fonte
1
Isso ocorreria porque NSObject implementa o seguinte na linha 70 do NSObject swiftDoc extension NSObject : Equatable, Hashable.
Adrian Sluyters de