Подтвердить что ты не робот

Switch: Enum Switch issue: не является членом int

Я пишу свой первый проект в Swift (я занимаюсь ObjectiveC в течение многих лет), и по какой-то причине я не могу понять, почему мой перечислитель и коммутатор не работают.

enum ContactViewMode : Int
    {
        case ViewModeFavourite = 0
        case ViewModeRecent = 1
        case ViewModeContacts = 2
    }

Недвижимость

 @IBInspectable var contactViewMode : Int!

Переключатель

switch contactViewMode {
            case ContactViewMode.ViewModeFavourite:
                contacts = DBManager.getFavouriteContacts() as [ContactEntity]
            case ContactViewMode.ViewModeRecent:
                contacts = DBManager.getFavouriteContacts() as [ContactEntity]
            default:
                contacts = DBManager.getAllContacts() as [ContactEntity]
        }

Ошибка, которую я получаю, Событие Enum 'ViewModeFavourite' не является членом типа 'Int!'

Итак, я изменил его на это, поскольку это не Int! (Мне нужен Int! Для раскадровки)

var contactMode:Int = contactViewMode

        switch contactMode {
            case .ViewModeFavourite:
                contacts = DBManager.getFavouriteContacts() as [ContactEntity]
            case .ViewModeRecent:
                contacts = DBManager.getFavouriteContacts() as [ContactEntity]
            default:
                contacts = DBManager.getAllContacts() as [ContactEntity]
        }

Тогда я получаю   Шаблон case Enum не может соответствовать значениям типа non-enum 'Int'

4b9b3361

Ответ 1

Вы должны объявить contactViewMode как contactViewMode, а не Int.

Если вы действительно хотите, чтобы он был Int, вам нужно изменить случаи в своем коммутаторе, сравнив переменную с свойством rawValue в случаях перечисления:

switch contactViewMode {
case ContactViewMode.ViewModeFavourite.rawValue:
    contacts = DBManager.getFavouriteContacts() as [ContactEntity]
case ContactViewMode.ViewModeRecent.rawValue:
    contacts = DBManager.getFavouriteContacts() as [ContactEntity]
default:
    contacts = DBManager.getAllContacts() as [ContactEntity]
}

но если у вас нет веских оснований для этого, я бы не рекомендовал

Ответ 2

Другие ответы не в состоянии использовать сильную типизацию Swifts. Обратите внимание, что все они имеют регистр по default в своем switch. Однако во время компиляции Swift знает, охватывали ли вы все случаи enum или нет, что делает ненужным случай по default.

Это полезная функция языка. Представьте, что вы добавите дополнительный case к своему enum на более позднем этапе. Компилятор будет жаловаться и указывать на все switch, которые не рассматривают этот конкретный case.

Как мы можем воспользоваться преимуществами строгой типизации Swifts?

Во-первых, давайте исправим наименование вашего перечисления. Поскольку я предполагаю, что вы ContactView класс ContactView (и, в отличие от Objective-C, он действительно должен быть внутри него), вы можете назвать enum просто Mode. Нет необходимости упоминать ViewMode в этих случаях. Таким образом, вы получите более чистый идиоматичный тип.

enum Mode: Int {
    case favourite
    case recent
    case contacts
}

Нам нужно выполнить switch в Mode, а не в Int. Ваш Mode является RawRepresentable, и поэтому вы можете сделать:

guard let m = Mode(rawValue: contactViewMode) else { /* handle the situation */ }
switch m {
    case .favourite: /* handle case */
    case .recent: /* handle case */
    case .contacts: /* handle case */
}

Вот и все, что нужно сделать - вместо того, чтобы rawValue, rawValue получите rawValue Mode а затем rawValue его.

Ответ 3

Это сработало для меня:

У меня есть перечисление вроде этого:

enum Proximity{
  case Unknown
  case Immediate
  case Near
  case Far
}

Затем появится переключатель, который выглядит так:

switch b.proximity as Proximity {
    case Proximity.Immediate:
         if b.rssi == -30 && b.accuracy == 0.2345{
             closestBeacon = b
         }
    case Proximity.Near:
         return
    case Proximity.Far:
         return
    default:
         return
 }

Im цикл через массив объектов "b", которые имеют свойство близости.

Ответ 4

Перечисления - это типы. Просто потому, что вы четко указываете, что одиночные значения перечисления могут быть отлиты до Int, не делает его действительным для объявления contactViewMode a Int!. Типы просто не совпадают.

Итак, объявляйте contactViewMode как contactViewMode, используйте свой первый оператор switch и добавьте в Int!, когда он действительно нужен для раскадровки, или используйте второй switch, но не используйте .ViewModeFacourite et al, но соответствующее значение Int.

var contactMode:Int = contactViewMode

    switch contactMode {
        case ContactViewMode.ViewModeFavourite.rawValue:
            contacts = DBManager.getFavouriteContacts() as [ContactEntity]
        case ContactViewMode..ViewModeRecent.rawValue:
            contacts = DBManager.getFavouriteContacts() as [ContactEntity]
        default:
            contacts = DBManager.getAllContacts() as [ContactEntity]
    }

Ответ 5

Вы не можете напрямую сопоставлять Int с enum. Вместо этого вам нужно преобразовать ContactViewMode в Int с свойством .rawValue, ИЛИ преобразовать Int в ContactViewMode с инициализатором init(rawValue:).

Последний пример:

switch ContactViewMode(rawValue: contactViewMode) {
case .Some(.ViewModeFavourite):
    contacts = DBManager.getFavouriteContacts() as [ContactEntity]
case .Some(.ViewModeRecent):
    contacts = DBManager.getFavouriteContacts() as [ContactEntity]
default:
    contacts = DBManager.getAllContacts() as [ContactEntity]
}

потому что ContactViewMode(rawValue:) возвращает опции, нам нужно .Some().

Ответ 6

Вы можете просто использовать contactViewMode и создать новую ContactViewMode типа ContactViewMode в случае, если значение contactViewMode приходит откуда-то еще, и оно должно быть int.

let contactMode :ContactViewMode = ContactViewMode(rawValue: contactViewMode)!

Теперь вы можете легко использовать переключатель, как показано ниже:

switch contactMode {
            case .ViewModeFavourite:
                contacts = DBManager.getFavouriteContacts() as [ContactEntity]
            case .ViewModeRecent:
                contacts = DBManager.getFavouriteContacts() as [ContactEntity]
            default:
                contacts = DBManager.getAllContacts() as [ContactEntity]
        }