web-dev-qa-db-fra.com

Switch: Enum Switch issue: non membre d'un int

J'écris mon premier projet à Swift (je fais ObjectiveC depuis des années) et pour une raison quelconque, je ne comprends pas pourquoi mon enum et Switch ne travaillent pas ensemble.

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

Propriété

 @IBInspectable var contactViewMode : Int!

Commutateur

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

L'erreur que j'obtiens est L'énumération 'ViewModeFavourite' n'est pas un membre de type 'Int!'

Donc je l'ai changé pour ceci car ce n'est pas un Int! (J'ai besoin d'Int! Pour Storyboard)

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]
        }

Alors je reçois Le modèle de cas Enum ne peut pas correspondre aux valeurs du type non-enum 'Int'

20
Burf2000

Vous devez déclarer contactViewMode comme ContactViewMode et non Int.

Si vous voulez vraiment que ce soit Int, vous devez changer les cas de votre commutateur en comparant la variable à la propriété rawValue des cas enum:

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]
}

mais à moins que vous n'ayez une bonne raison à cela, je ne recommanderais pas

27
Antonio

Les autres réponses ne tirent pas profit de la frappe puissante de Swift. Notez qu'ils ont tous un cas default dans leur switch. Cependant, Swift sait au moment de la compilation si vous avez couvert ou non tous les cas de enum ou non, rendant ainsi le cas de default inutile.

C'est une fonctionnalité utile du langage. Imaginez que vous ajoutiez une case supplémentaire à votre enum ultérieurement. Le compilateur se plaindra et vous indiquera toutes les switches qui ne considèrent pas cette case particulière.

Comment pouvons-nous tirer parti de la frappe puissante de Swift, alors?

Commençons par fixer le nom de votre énumération. Comme je suppose que vous l'insérez dans une classe ContactView (et, contrairement à Objective-C, il devrait en réalité être inside it), vous pouvez nommer la enum simplement Mode. Inutile de mentionner ViewModes dans les cas non plus. De cette façon, vous obtenez un type plus propre, plus idiomatique.

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

Ce que nous devons faire, c'est exécuter la switch sur une Mode et non sur une Int. Votre Mode est RawRepresentable et, en tant que tel, vous pouvez faire:

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

C’est tout ce qu’il ya à faire - au lieu d’allumer la rawValue, obtenez d’abord la Mode appropriée puis allumez-la.

20
Quico Moya

Cela a fonctionné pour moi:

J'ai un enum comme ça:

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

Ensuite, un commutateur qui ressemble à ceci:

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
 }

Je boucle dans un tableau d'objets "b" qui ont une propriété de proximité.

6
Jon Vogel

Les énumérations sont des types. Le simple fait de préciser que les valeurs simples enum peuvent être converties en Int ne le rend pas valide pour déclarer contactViewMode un Int!. Les types ne correspondent tout simplement pas.

Donc, déclarez contactViewMode en tant que ContactViewMode, utilisez votre première instruction switch et transformez en Int! lorsque vous en avez réellement besoin pour le storyboard ou utilisez la seconde switch, mais n'utilisez pas .ViewModeFacourite et autres, mais la valeur Int correspondante.

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]
    }
4
Thorsten Dittmar

Vous ne pouvez pas associer directement Int à enum. Au lieu de cela, vous devez convertir ContactViewMode en Int avec la propriété .rawValue, OR convertir Int en ContactViewMode avec init(rawValue:) initializer.

Le dernier exemple:

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]
}

Étant donné que ContactViewMode(rawValue:) renvoie des options, nous avons besoin de .Some().

3
rintaro

Vous pouvez simplement utiliser contactViewMode et créer une nouvelle variable de type ContactViewMode si la valeur de contactViewMode provient d'ailleurs et doit être int.

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

Maintenant, vous pouvez facilement utiliser le commutateur comme indiqué ci-dessous:

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