Ceci est un article pour les débutants. Même si vous n'êtes pas débutant, vous découvrirez peut-être quelque chose. J'écrirai sur l'énumération de la grammaire Swift.
Fonctionnement confirmé avec Swift 5.3
La valeur brute et la valeur associée peuvent-elles être utilisées en même temps dans l'énumération de Swift?
Si vous savez cela, vous n'aurez peut-être pas besoin de lire cet article en particulier.
enum C'est ce qu'on appelle un type d'énumération. Défini avec enum et case.
enum CompassPoint {
case north
case south
case east
case west
}
Les variables sont ** singulières **.
Si vous connaissez le type d'énumération de la variable, vous pouvez omettre le type comme .east
.
var directionToHead = CompassPoint.north
directionToHead = .south
var directionToHeadLast: CompassPoint = .east
Switch Dans l'instruction Switch, une erreur de compilation se produit si tous les cas d'énumération ne sont pas couverts. Vous pouvez également utiliser default.
switch directionToHead {
case .north, .east, .south, .west: print("direction")
}
switch directionToHead {
case .north, .east, .south: print("direction")
default: print("other")
}
En ajoutant CaseIterable, vous pouvez transformer l'élément d'énumération avec une instruction for.
C'est comme ça
enum CompassPoint: CaseIterable {
case north
case south
case east
case west
}
CompassPoint.allCases.forEach{print($0)}
Cela produira ce qui suit:
north
south
east
west
Associated Values
Il est possible de donner une valeur à chaque élément d'énumération.
enum Appliance {
case light(isOn: Bool)
case airCon(degree: Int, isOn: Bool)
}
var appliance: Appliance
appliance = .light(isOn: true)
appliance = .airCon(degree: 28, isOn: true)
Lorsque vous l'utilisez dans une instruction Switch, vous pouvez récupérer la valeur associée avec let ou var.
switch appliance {
case .light(let isOn):
print(isOn)
case .airCon(let degree, let isOn):
print(isOn, degree)
}
Notez que le Case Iterable sorti précédemment ne peut pas être utilisé pour les énumérations avec ** Valeurs associées **!
Lorsque la valeur associée est all let ou all var, elle est multipliée comme suit.
switch appliance {
case let .light(isOn):
print(isOn)
case let .airCon(degree, isOn):
print(isOn, degree)
}
Vous n'êtes pas obligé d'écrire plusieurs let en mettant let
devant!
Raw Values
Contrairement aux valeurs associées, vous pouvez mettre des ** valeurs qui sont ** fixées au moment de l'écriture dans chaque cas d'énumération.
enum Step: Int {
case one = 1
case two = 2
case three = 3
}
print(Step.three.rawValue)
Cela affichera «3».
enum Step: Int {
case one, two, three
}
print(Step.one.rawValue)
Que pensez-vous que cela montrera?
Réellement
0
Est affiché.
Ce n'est que lorsqu'il s'agit d'une valeur brute de Int ou de chaîne, la valeur est entrée sans autorisation. Dans le cas de Int, «0» entre dans le premier cas et est incrémenté un par un. Dans le cas de String, le nom du cas lui-même est entré.
Faisons plus sur la valeur brute. Cela posera des problèmes, alors devinons la chaîne de caractères de sortie.
Q1
enum Step: Int,CaseIterable {
case one, two, three=99
}
Step.allCases.forEach{print($0.rawValue)}
<détails> Q2 <détails> Q3 <détails> Il y a une erreur de compilation.
Pour trois, 12 est entré, ce qui est un incrément de 11 pour deux, mais je me fâche parce que cela est couvert par un. Q4 <détails> C'est aussi une erreur de compilation
Int8 a un maximum de 127, donc je me fâche lorsque les trois valeurs dépassent int8. Cela peut aller de rawValue à enum.
Notez que si vous spécifiez une valeur qui n'est pas dans enum, elle sera ** nil **! En d'autres termes, la valeur de retour sera facultative lors de l'initialisation avec rawValue.
Utiliser la liaison facultative lors de l'initialisation avec rawValue C'est le premier problème. La réponse est «peut» Si vous l'avez fait normalement, ce code J'obtiens une erreur de compilation. Cependant, en réalité, il peut être géré. La manière d'écrire la valeur brute d'énumération expliquée cette fois est appelée «notation abrégée». Il est écrit comme suit. La condition pour réaliser RawValue est le respect du protocole «RawRepresentable», qui se trouve également dans l'erreur de compilation ci-dessus.
Si le cas a au moins une valeur associée, la «notation abrégée» ne sera plus automatiquement conforme à «RawRepresentable».
Ainsi, vous pouvez utiliser la valeur brute et la valeur associée en même temps en procédant comme suit. Notez que vous devez saisir la valeur associée lors de l'initialisation. Après tout, la manière d'écrire RawValue de Si vous souhaitez utiliser enum de manière récursive pour une valeur associée, vous devez ajouter le mot clé indirect à ce cas. Indirect peut également être amené au début de l'énumération. Erreur de compilation Je souhaite afficher l'expression sous forme de chaîne de caractères dans l'impression ci-dessus.
J'ai essayé d'afficher la chaîne de caractères de l'expression de manière récursive à l'aide de CustomStringConvertible. Est-ce que c'est comme ça? Il a été affiché en toute sécurité!0
1
99
enum Step: Int,CaseIterable {
case one, two=99, three
}
Step.allCases.forEach{print($0.rawValue)}
0
99
100
enum Step: Int,CaseIterable {
case one=12, two=11, three
}
Step.allCases.forEach{print($0.rawValue)}
enum Step: Int8,CaseIterable {
case one, two=127, three
}
Step.allCases.forEach{print($0.rawValue)}
error: MyPlayground.playground:12:24: error: integer literal '128' overflows when stored into 'Int8'
case one, two=127, three
Initialiser avec la valeur brute
enum Step: Int, CaseIterable {
case one=1, two, three
}
Step(rawValue: 2) // two
Step(rawValue: 4) // nil
guard let step = Step(rawValue: 4) else {
fatalError("undefined!!")
}
La valeur brute et la valeur associée peuvent-elles être utilisées en même temps dans l'énumération de Swift?
enum CompassPoint: String {
case north(Int)
case south(Int)
case east(Int)
case west(Int)
}
'CompassPoint' declares raw type 'String', but does not conform to RawRepresentable and conformance could not be synthesized
enum Test: String {
case pass = "Yay!"
}
enum TestResult {
case pass(Int)
case fail(Int)
}
extension TestResult: RawRepresentable {
typealias RawValue = String
init?(rawValue: RawValue) {
switch rawValue {
case "Yay!": self = .pass(1)
case "Pardon ...": self = .fail(0)
default:
return nil
}
}
var rawValue: RawValue {
switch self {
case .pass: return "Yay!"
case .fail: return "Pardon ..."
}
}
}
TestResult.pass(1).rawValue //Yay!
TestResult.fail(0).rawValue //Pardon ...
notation abrégée 'n'est qu'une courte expression, et il semble que le compilateur en fasse
RawRepresentable` comme ci-dessus. (Référence: The RawRepresentable Protocol in Swift - Ole Begemann)Énumération récursive
enum ArithmeticExpression {
case number(Int)
indirect case addition(ArithmeticExpression, ArithmeticExpression) //Récursif car l'argument ici se contient
}
indirect enum ArithmeticExpression: CustomStringConvertible {
case number(Int)
case addition(ArithmeticExpression, ArithmeticExpression)
}
Sans indirect?
error: MyPlayground.playground:2:6: error: recursive enum 'ArithmeticExpression' is not marked 'indirect'
enum ArithmeticExpression: CustomStringConvertible {
^
indirect
J'ai essayé d'afficher une chaîne de caractères pendant un moment
let expression = ArithmeticExpression.addition(.number(10), .addition(.number(1), .number(2)))
print(expression.description)
enum ArithmeticExpression: CustomStringConvertible {
case number(Int)
indirect case addition(ArithmeticExpression, ArithmeticExpression)
var description: String {
get {
switch self {
case .number(let num):
return String(num)
case .addition(let expr1, let expr2):
return "\(expr1.description) + \(expr2.description)"
}
}
}
}
10 + 1 + 2
Sommaire
référence