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-sourceLook for_findStringSwitchCaseMethod 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.)