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'
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
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 switch
es 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 ViewMode
s 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.
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é.
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]
}
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()
.
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]
}