Перегрузка оператора равенства в быстрых перечислениях со связанными значениями

Я знаю, что почти аналогичный вопрос задавался ранее, но я не могу его прокомментировать, потому что я здесь новичок. Вот почему я публикую отдельный вопрос. Также мой вопрос является продолжением предыдущего заданного вопроса и направлен на более общее решение. Это ссылка на предыдущий вопрос: Как проверить равенство перечислений Swift со связанными значениями

Я хочу проверить равенство в перечислении со связанными значениями:

enum MyEnum {
    case None
    case Error
    case Function(Int) // it is a custom type but for briefness an Int here
    case ...
}

Я попытался настроить функцию перегрузки следующим образом.

func ==(a: MyEnum, b: MyEnum) -> Bool {
    switch (a,b) {
    case (.Function(let aa), .Function(let bb)):
        if (aa==bb) {
            return true
        } else {
            return false
        }
    default:
        if (a == b) {
            return true
        } else {
            return false
        }
    }
}

Это не дает ошибки времени компиляции, но завершается с ошибкой bad_exec в запущенном процессе. Скорее всего потому, что проверка a==b в случае по умолчанию снова вызывает саму функцию. Часть .Function работает, как и ожидалось, но не все остальное... Итак, список случаев несколько длиннее, как я могу проверить случаи, которые не имеют связанного с ними значения, на равенство?


person enovatia    schedule 09.03.2015    source источник
comment
Я только что добавил ответ здесь: stackoverflow.com/a/41034836/2784160   -  person LShi    schedule 08.12.2016


Ответы (2)


В вашей реализации

if (a == b) {

рекурсивно снова вызывает ту же функцию ==. В конечном итоге это приводит к сбою с переполнением стека.

Например, рабочая реализация будет такой:

func ==(a: MyEnum, b: MyEnum) -> Bool {
    switch (a,b) {
    case (.Function(let aa), .Function(let bb)):
        return aa == bb
    case (.Error, .Error):
        return true
    case (.None, .None):
        return true
    default:
        return false
    }
}
person Martin R    schedule 09.03.2015
comment
К сожалению, вы уже заметили рекурсию (извините за недостаточно внимательное прочтение вопроса). Посмотрим, не появится ли лучшее решение... - person Martin R; 09.03.2015
comment
Тем не менее спасибо за публикацию этого! Потому что для короткого списка перечислений это, вероятно, лучшее и простое решение. И это прямо вперед. Но если у вас длинный список случаев, мне все еще интересно, есть ли более элегантное (и более короткое) решение. Потому что было бы много писать для очень простого вопроса... lhs равно rhs - person enovatia; 09.03.2015

Хотя memcmp работает:

func ==(var a: MyEnum, var b: MyEnum) -> Bool {
    switch (a,b) {
    case (.Function(let aa), .Function(let bb)):
        return aa == bb
    default:
        return memcmp(&a, &b, sizeof(MyEnum)) == 0
    }
}

Я не рекомендую это :)

person rintaro    schedule 09.03.2015