Summary of Swift progress
Preface:
In Swift language, there are three types with class characteristics, namely enumerated types, structural types (including basic types, which are actually special cases of structural types) and classes. Enumeration type and structure type belong to value type, and class belongs to reference type. All three types can add attributes, methods, subscripts, function extensions, protocols, etc. Let’s share the enumeration types in Swift.
C language enumeration writing review
Before we enumerate Swift, let’s review the C language enumeration method:
Enum Enum name {Enumeration value 1, enumeration value 2,...... }; <! -- Example: 7 days a week --> enum Weak{MON, TUE, WED, THU, FRI, SAT, SUN}; <! Enum Weak{MON = 1, TUE, WED, THU, FRI, SAT, SUN}; enum Weak{MON = 1, TUE, WED, THU, FRI, SAT, SUN}; <! Weak enum weak {MON = 1, TUE, WED, THU, FRI, SAT, SUN}weak {MON = 1, TUE, WED, THU, FRI, SAT, SUN}weak; Enum {MON = 1, TUE, WED, THU, FRI, SAT, SUN}weak;Copy the code
Analogies to enumeration writing in Swift
Going back to the Swift enumeration, let’s consider an example: let’s say we want to specify a color enumeration LGColor, in
What should I say in Swift
enum Weak { case MONDAY case TUEDAY case WEDDAY case THUDAY case FRIDAY case SATDAY case SUNDAY } <! -- -- -- -- -- -- -- -- -- -- can also write -- -- -- -- -- -- -- -- -- -- - > enum Weak {case MON, TUE, WED and THU, FRI, SAT, SUN}Copy the code
In the above code our enumeration values are integers by default. This C is consistent. What if we want to express strings?
enum Weak: String { case MON = "MON" case TUE = "TUE" case WED = "WED" case THU = "THU" case FRI = "FRI" case SAT = "SAT" case SUN = "SUN" } <! -- -- -- -- -- -- -- the hermit's writing method -- -- -- -- -- -- -- > enum Weak: Int {mon, tue, wed and thu, fri = 10, sat, sun} <! -------String type ----------> enum Weak: String { case mon, tue, wed, thu, fri = "Hello", sat, sun } print(Weak.mon.rawValue) print(Weak.fri.rawValue)Copy the code
The value to the left of the = sign is called RawValue in Swift. If we don’t want to write the following string, then we can use ‘Hermit RawValue assignment’
Traversal of enumeration
Enumerations in Swift can be traversed like collections
enum Weak: String { case mon, tue, wed, thu, fri = "Hello", sat, sun } extension Weak: CaseIterable{} var allCase = Weak.allCases <! 1: -- -- -- -- -- -- -- way for loop -- -- -- -- -- -- -- > for c in allCase {print (c)} <! ----- Print result ------> mon tue wed thu fri sat sun <! Let allCase = Weak. AllCases. Map ({"\($0)"}). Joined (separator: ", ") print(allCase) <! ----> mon, tue, wed, thu, FRi, sat, sunCopy the code
The CaseIterable protocol is usually used for enumerations without associated values. It is used to access all enumerations as long as the corresponding enumerations comply with the protocol, and then all enumerations are retrieved through allCases
Enumeration associated value
If you want to use enumerations to represent complex meanings and relate more information, you need to use associated values
For example, if we use enum to express a shape, which has a circle, a rectangle, etc., the circle has a radius, and the rectangle has a width and height, we can represent it by enum with associated values below
Radius case circle(radius: Double) case Rectangle (width: Int, height: Int)} <! ----- use -----> <! Var shape = shape. circle(radius: 10.0) <! Rectangle (width: 10, height: 10); rectangle(width: 10, height: 10); rectangle(rectangle(width: 10, height: 10)); Print (" rectangle :\(radius*radius)") case. Rectangle (let with,let height) print(" rectangle :\(with*height)")} case let .circle(radius): Print (" rectangle :\(radius*radius)") case let. Rectangle (with,height) print(" rectangle :\(with*height)")} If case. Circle (let width) = s {print(width)} // 2. Declare all associated content types of case (e.g. var) if case var .rectangle(radius, borderWidth) = c { radius += 200 borderWidth += 100 print(radius, borderWidth) }Copy the code
Enumerations with associated values have no rawValue attribute, mainly because a case can be represented by one or more values, whereas rawValue has only a single value
Nesting of enumerations
The nesting of enumerations is mainly used in the following scenarios:
-
A complex enumeration is composed of one or more enumerations (enumerations nested enumerations)
-
Enum is not public, that is, private (struct nested enumeration)
Enumeration nested enumeration
For example, the arrow keys in the game, for example, there are four arrow keys, up, down, left and right, different combinations will move in different directions
Enum CombineDirect{// Nested enumeration in enumeration enum BaseDirect{case Up case Down case Left case Right} // Enumeration value combined through internal enumeration case leftUp(baseDIrect1: BaseDirect, baseDirect2: BaseDirect) case leftDown(baseDIrect1: BaseDirect, baseDirect2: BaseDirect) case rightUp(baseDIrect1: BaseDirect, baseDirect2: BaseDirect) case rightDown(baseDIrect1: } // Use let leftUp = combinedirect. leftUp(baseDIrect1: BaseDirect) CombineDirect.BaseDirect.left, baseDirect2: CombineDirect.BaseDirect.up)Copy the code
Structure nested enumerations
Struct Skill {enum KeyType{case up case down case left case right} let key: KeyType func launchSkill(){ switch key { case .left, .right: print("left, right") case .up, .down: print("up, down") } } }Copy the code
Enumerations contain attributes
The enum contains only calculation attributes and type attributes, but not storage attributes
enum Shape{ case circle(radius: Double) case rectangle(width: Double, height: Double) // Enums must not contain stored properties because enum is a value type. Var with: Double{get{return 10.0}} static let height = 20.0}Copy the code
Enumerations contain methods
Instance methods, static modified methods, can be defined in enum
enum Weak: Int{ case MON, TUE, WED, THU, FRI, SAT, SUN mutating func nextDay(){ if self == .SUN{ self = Weak(rawValue: 0)! }else{ self = Weak(rawValue: self.rawValue+1)! }}} <! Var w = Weak.MON w.extday () print(w)Copy the code
SIL analysis of enumerations
Sil analysis
Take the DayOfWeak enumeration as an example to see how the enumeration is compiled and valued
enum DayOfWeak:String { case monday ,tuesday ,wednesday = "Hello" ,thursday ,friday ,saturday ,sunday } print(DayOfWeak.monday.rawValue) print (DayOfWeak.wednesday.rawValue) <! ------- Print result -----> Monday HelloCopy the code
Enter the SIR file to view enumeration details
What happens to RawValue that outputs the current case?
Looking at getter methods
The essence of using rawValue is to call the GET method, but where does the String in the GET method come from? Where is String stored? In fact, the strings corresponding to the branches are stored at compile time, that is, in the __text. cstring of the Maach-o file, and are contiguic memory space, which can be verified by viewing the Mach-O file after compile
A string retrieved from the address of the Mach-o file and then returned to W
The difference between an enumerated value and RawValue
Look at the differences between enumerated values and rawValues from the following example
enum DayOfWeak:String { case monday ,tuesday ,wednesday = "Hello" ,thursday ,friday ,saturday ,sunday } print (DayOfWeak.monday) print(DayOfWeak.monday.rawValue) <! ------ Print result -----> Monday MondayCopy the code
All of the above are printed as “Monday”. Does that mean the enumeration value and RawValue are the same thing? The first output is the case enumeration of the output. The second output is the GET method of rawValue accessed through rawValue
An example is to define a variable of type String and assign it a value
So print is the enumeration value and rawValue is the rawValue get method
How do I access the enumeration values of enUms?
SIR File Analysis
Initialization returns Optional, and DayOfWeak is assigned to %19
Index_addr is basically the address of the NTH element in the current array, and then you put the constructed string into the current address. When we specify RawValueType of enum as String, the system automatically creates a contiguous memory space to store the String corresponding to the current case by default.
Continue branch
That’s the process of enumerating matches
Supplement:
_findStringSwitchCase
swift-source
Look for_findStringSwitchCase
Method that takes two arguments, respectivelyArray + String to match
Conclusion:
-
The essence of using rawValue in enum is to call the GET method, the operation in which a string is fetched from the mach-O corresponding address and returned
-
Init (rawValue 🙂 or enum (rawValue 🙂
-
If you want to get all the enumerations, you need to follow the CaseIterable protocol and get them by enumeration.allCase
-
Case enumerated value = rawValue rawValue
To be continued…. (The next article continues to analyze enumerations using sil.)