Почему эквивалентный протокол должен быть определен вне класса?

Когда я реализую протокол Hashable. функция эквивалентного протокола должна быть определена вне класса следующим образом. Следующим образом.

func ==(lhs: Swap, rhs: Swap) -> Bool {
    return (lhs.cookieA == rhs.cookieA && lhs.cookieB == rhs.cookieB) ||
        (lhs.cookieB == rhs.cookieA && lhs.cookieA == rhs.cookieB)
}

class Swap: Printable,Hashable {
    var cookieA: Cookie
    var cookieB: Cookie

    init(cookieA: Cookie, cookieB: Cookie) {
        self.cookieA = cookieA
        self.cookieB = cookieB
    }
    var hashValue: Int {
    return cookieA.hashValue ^ cookieB.hashValue
    }

    var description: String {
    return "swap \(cookieA) with \(cookieB)"
    }
}

Это просто немного странно для меня. В приведенном выше примере функция func == должна принадлежать классу Swap. Итак, почему нам нужно объявлять func == вне класса??


person Siu Chung Chan    schedule 18.07.2014    source источник
comment
equatable, естественно, является классом типов… а экземпляры класса типов определяются вне типов. book.realworldhaskell.org/read/using-typeclasses.html   -  person Display Name    schedule 13.10.2014


Ответы (3)


Главным образом потому, что это функция, а не метод. Функции не зависят от классов, поэтому нет смысла ограничивать их область действия объявлениями классов.

Протокол мог быть разработан с использованием методов, например. используя метод obj1.isEqualTo(obj2), но функция менее чувствительна к проблемам nil. Если бы obj1 было nil, метод потерпел бы неудачу.

person Sulthan    schedule 18.07.2014

Я бы не стал вчитываться в это слишком много. Я думаю, что это простое дизайнерское решение. Да, во многих языках перегруженные операторы — это методы для левого операнда, и это нормально, но определение операторов как функций, вероятно, дает вам немного больше гибкости, поэтому они решили сделать их все функциями.

person radex    schedule 18.07.2014

Функция оператора определяется как глобальная функция с именем функции, которое соответствует перегружаемому оператору. Функция определяется глобально, а не как метод целевого класса или структуры, поэтому ее можно использовать в качестве инфиксного оператора между существующими экземплярами целевого класса или структуры.

Я подробно ответил на этот вопрос в своем сообщении в блоге здесь. Надеюсь, поможет.

person jarora    schedule 17.05.2016