webentwicklung-frage-antwort-db.com.de

Switch: Enum Switch Problem: Nicht Mitglied eines Int

Ich schreibe mein erstes Projekt in Swift (ich mache seit Jahren ObjectiveC) und aus irgendeinem Grund kann ich nicht herausfinden, warum mein Enum und Switch nicht zusammen funktionieren

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

Eigentum

 @IBInspectable var contactViewMode : Int!

Schalter

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

Der Fehler, den ich erhalte, ist Enum-Case 'ViewModeFavourite' ist kein Member vom Typ 'Int!'

Also habe ich es geändert, da es kein Int ist! (Ich brauche Int! Für 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]
        }

Dann bekomme ich Enum-Case-Muster kann nicht mit Werten des Nicht-Enummentyps 'Int' übereinstimmen

20
Burf2000

Sie müssen contactViewMode als ContactViewMode und nicht als Int deklarieren.

Wenn Sie wirklich Int wünschen, müssen Sie die Fälle in Ihrem Switch ändern, indem Sie die Variable mit der rawValue-Eigenschaft der Enumerationsfälle vergleichen:

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

aber wenn Sie keinen guten Grund dafür haben, würde ich nicht empfehlen

27
Antonio

Die anderen Antworten können die Vorteile von Swifts starkem Tippen nicht nutzen. Beachten Sie, dass sie alle einen default-Fall in ihrer switch haben. Swift weiß jedoch zur Kompilierzeit, ob Sie alle Fälle einer enum behandelt haben oder nicht, wodurch der default-Fall unnötig wird.

Dies ist eine nützliche Funktion der Sprache. Stellen Sie sich vor, Sie fügen zu einem späteren Zeitpunkt eine zusätzliche case zu Ihrer enum hinzu. Der Compiler beschwert sich und weist Sie auf alle switches hin, die diese bestimmte case nicht berücksichtigen.

Wie können wir dann das starke Tippen von Swift nutzen?

Zuerst wollen wir die Benennung Ihrer Aufzählung festlegen. Da ich davon ausgehe, dass Sie es in einer ContactView-Klasse verschachteln (und anders als in Objective-C sollte es wirklich inside it sein), können Sie die enum einfach Mode nennen. In den Fällen müssen Sie auch nicht ViewModes erwähnen. Auf diese Weise erhalten Sie einen saubereren, idiomatischeren Typ.

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

Was wir tun müssen, ist die switch mit einer Mode und nicht mit einer Int. Ihre Mode ist RawRepresentable, und als solche können Sie Folgendes tun:

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

Das ist alles, was dazu gehört - statt die rawValue einzuschalten, besorgen Sie sich zuerst die richtige Mode und schalten Sie sie dann ein.

20
Quico Moya

Das hat für mich funktioniert:

Ich habe eine Aufzählung wie diese:

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

Dann ein Schalter, der so aussieht:

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 Schleifen durch ein Array von "b" Objekten, die eine Eigenschaft für die Nähe haben.

6
Jon Vogel

Aufzählungen sind Typen. Nur weil Sie deutlich machen, dass die einzelnen Enummenwerte in Int umgewandelt werden können, ist es nicht zulässig, contactViewMode als Int! zu deklarieren. Die Typen passen einfach nicht zusammen.

So deklarieren Sie entweder contactViewMode als ContactViewMode, verwenden Sie Ihre erste switch-Anweisung und wandeln Sie in Int! um, wenn Sie es tatsächlich für das Storyboard benötigen, oder verwenden Sie die zweite switch. Verwenden Sie jedoch nicht .ViewModeFacourite et al, sondern den entsprechenden Int-Wert.

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

Sie können Int nicht direkt mit enum vergleichen. Stattdessen müssen Sie ContactViewMode in Int mit .rawValue-Eigenschaft konvertieren, OR konvertieren Int in ContactViewMode mit init(rawValue:)-Initialisierung.

Letzteres Beispiel:

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

da ContactViewMode(rawValue:) Optionals zurückgibt, benötigen wir .Some().

3
rintaro

Sie können einfach contactViewMode verwenden und eine neue Variable vom Typ ContactViewMode erstellen, falls der Wert von contactViewMode von woanders kommt und int sein muss.

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

Jetzt können Sie den Schalter wie folgt verwenden:

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