Swift Learning note-enumeration (enumerations)

Source: Internet
Author: User
Tags control characters

The contents of this page include:

    • Enumeration syntax (enumeration Syntax)
    • Match enumeration values with Swith statements (Matching enumeration values with a Switch Statement)
    • Correlation value (associated values)
    • Original value (Raw values)
    • Recursive enumeration (Recursive enumerations)

Enumerations define a set of related values for a common type, so that you can use them in a safe way in your code.

If you are familiar with the C language, you will know that in C the enumeration corresponds to an integer value. The enumerations in Swift are more flexible and do not have to provide a value for each enumeration member. If you supply an enumeration member with a value (called the "original" value), the type of the value can be a string, a character, or an integer value or a floating-point number.

In addition, enumeration members can specify that any type of related value is stored in an enumeration member value, just like a union (unions) and variant (variants) in other languages. You can define a common set of related members as part of an enumeration, each with a different set of values of the appropriate type associated with it.

In Swift, the enumeration type is a one-class citizen (first-class). They employ a number of features traditionally supported only by Class (class), such as computed attributes (computed properties), which provide additional information about enumerating the current values, instance methods (instance methods), Used to provide and enumerate the functions that are associated with the value represented by the enumeration. Enumerations can also define constructors (initializers) to provide an initial value, extend their functionality on the basis of the original implementation, and can comply with the Protocol (protocols) to provide standard functionality.

For more information, see Properties, Methods (Methods), construction procedures (initialization), extensions (Extensions), and protocols (protocols).

Enumeration syntax

Use enum keywords to create enumerations and place their entire definition within a pair of curly braces:

enum SomeEnumeration {  // 枚举定义放在这里}

Here is an example of the compass in four directions:

enum CompassPoint {  case North  case South  case East  case West}

The values defined in the enumeration (for example North , South , East and West ) are the member values (or members) of this enumeration. caseThe keyword indicates that a row of new member values will be defined.

Note: Unlike C and Objective-c, Swift's enumeration members are not assigned a default integer value when they are created. In the example above,,, CompassPoint North South East and West not implicitly assigned to 0 , 1 , 2 and 3 . Instead, the enumeration members themselves have complete values that are well-defined CompassPoint types.

Multiple member values can appear on the same line, separated by commas:

enum Planet {  case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune}

Each enumeration defines a completely new type. Like other types in Swift, their names (such as CompassPoint and Planet ) must begin with a capital letter. A single-digit name instead of a plural name for an enumeration type to make it easier to read:

var directionToHead = CompassPoint.West

directionToHeadType can be CompassPoint inferred when it is initialized with a possible value. Once directionToHead declared as one CompassPoint , you can use an abbreviation syntax (.) to set it to another CompassPoint value:

directionToHead = .East

When directionToHead the type is known, the enumeration name can be omitted when the value is assigned again. Using an explicit type of enumeration value can make your code more readable.

Match enumeration values and SwitchStatement

You can use switch statements to match a single enumeration value:

directionToHead = .Southswitch directionToHead {    case .North:        print("Lots of planets have a north")    case .South: print("Watch out for penguins") case .East: print("Where the sun rises") case .West: print("Where the skies are blue")}// 输出 "Watch out for penguins”

You can understand this code this way:

" directionToHead the value of the judgment. When it equals .North , print “Lots of planets have a north” . When it equals .South , print “Watch out for penguins” . ”

And so on.

As described in control flow, the switch statement must be exhaustive in all cases when judging the value of an enumerated type. If this is omitted .West , the code above will not compile because it does not take into account CompassPoint all the members. Mandatory full exhaustive requirements ensure that enumeration members are not accidentally omitted.

When you do not need to match each enumeration member, you can provide a default default branch to cover all enumerated members that are not explicitly presented:

let somePlanet = Planet.Earthswitch somePlanet {case .Earth:    print("Mostly harmless")default: print("Not a safe place for humans")}// 输出 "Mostly harmless”

Correlation value (associated values)

The example in the previous section demonstrates how to define (classify) the members of an enumeration. You can Planet.Earth set a constant or variable, and look at the value after the assignment. In any case, it is useful to be able to store other types of related values together with member values sometimes. This allows you to store custom information outside of a member's value and allow this information to change every time you use that member in your code.

You can define Swift's enumeration to store any type of related value, and the data type of each member can be different if required. This attribute of the enumeration is similar to the recognizable union (discriminated unions) in other languages, the label union (tagged unions), or the variant (variants).

For example, suppose an inventory tracking system needs to use two different types of barcodes to track goods. Some products are marked with a one-dimensional barcode in upc-a format, which uses numbers 0 through 9. Each barcode has a number representing the "digital system" followed by 5 numbers representing the "Production Code", followed by a 5-bit "Product Code". The last number is the "check" bit to verify that the code is scanned correctly:

Other products are labeled QR code format, it can use any ISO 8859-1 characters, and can encode a maximum of 2,953 characters of the string:

For the inventory tracking system, it is convenient to store the UPC-A code as a tuple of four integer values, and the QR code as a string of any length.

In Swift, you define an enumeration of two commodity barcodes using the following method:

enum Barcode {  case UPCA(Int, Int, Int, Int)  case QRCode(String)}

The above code can understand this:

"Defines an Barcode enumeration type named, which can be a UPCA correlation value (,,, Int Int Int Int ), or a QRCode string type ( String ) related value. ”

This definition does not provide any Int or String actual value, it simply defines the Barcode Barcode.UPCA Barcode.QRCode type of the relevant value when the constant and variable are equal or.

You can then use any one of the barcode types to create new barcodes, such as:

var productBarcode = Barcode.UPCA(8, 85909, 51226, 3)

The above example creates a variable named and productBarcode assigns it a Barcode.UPCA related tuple value (8, 85909, 51226, 3) .

The same product can be assigned to a different type of barcode, such as:

productBarcode = .QRCode("ABCDEFGHIJKLMNOP")

At this point, the original Barcode.UPCA and its integer value are replaced by the new Barcode.QRCode and its string values. The bar code constants and variables can store one .UPCA or .QRCode the other (along with its associated values), but only one of them will be stored at any given time.

As before, different barcode types can be checked using a switch statement, but this time the correlation value can be extracted as part of the switch statement. You can switch extract each correlation value in the case branch code as a constant ( let prefixed) or as a variable ( var prefixed) to use:

switch productBarcode {case .UPCA(let numberSystem, let manufacturer, let product, let check): print("UPC-A: \(numberSystem), \(manufacturer), \(product), \(check).")case .QRCode(let productCode): print("QR code: \(productCode).")}// 输出 "QR code: ABCDEFGHIJKLMNOP."

If all the relevant values of an enumeration member are extracted as constants, or they are all extracted as variables, for brevity, you can just place one var or let label it before the member name:

switch productBarcode {case let .UPCA(numberSystem, manufacturer, product, check):    print("UPC-A: \(numberSystem), \(manufacturer), \(product), \(check).")case let .QRCode(productCode): print("QR code: \(productCode).")}// 输出 "QR code: ABCDEFGHIJKLMNOP."

Original value (Raw values)

The bar code example in the related Values section demonstrates how a member of an enumeration declares that they store related values of different types. As an alternative to a related value, an enumeration member can be assigned a value by default (called the original value), where the original values have the same type.

Here is an example of an enumeration member storing ASCII code:

enum ASCIIControlCharacter: Character {    case Tab = "\t"    case LineFeed = "\n" case CarriageReturn = "\r"}

Here, ASCIIControlCharacter the original value type of the enumeration type is defined as a character type Character , and some of the more common ASCII control characters are set. For a description of the character value, see the String and Character section.

The original value can be a string, a character, or any integral or floating-point value. Each original value must be unique within its enumeration declaration.

Attention:
The original value and the correlation value are not the same. When you start defining enumerations in your code, the original values are pre-populated values like the above three ASCII codes. For a particular enumeration member, its original value is always the same. The correlation value is set when you create a new constant or variable based on an enumeration member, and each time you do so, its value can be different.

Implicit assignment of the original value (implicitly Assigned raw values)

You do not need to explicitly assign a value to each member when using an enumeration of the original value as an integer or string type, and Swift will automatically assign you a value.

For example, when an integer is used as the original value, the value of the implicitly assigned value increments by 1. If the first value is not assigned the initial values, it will be automatically set to 0.

The following enumeration is a refinement of the previous Planet enumeration, using the original integer values to represent the order of each planet in the solar system:

enum Planet: Int {    case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune}

In the above example, an initial value is assigned, and an Plant.Mercury 1 Planet.Venus implicit assignment is given 2 , and so on.

When a string is used as the initial value of an enumeration type, the implicit initial value of each enumeration member is the name of the member.

The following example is a CompassPoint lite version of an enumeration type, using a string as the initial value type, implicitly initialized to the name of each direction:

String {    case North, South, East, West}

In the example above, there is CompassPoint.South an implicit initial value South , and so on.

The rawValue original value of the enumeration member can be accessed by using the properties of the enumeration member:

let earthsOrder = Planet.Earth.rawValue// earthsOrder 值为 3let sunsetDirection = CompassPoint.West.rawValue// sunsetDirection 值为 "West"
Initialize enumeration variables with raw values (Initializing from a raw value)

If the original value is used when defining an enumeration type, an initialization method is automatically obtained, which takes the original value type as an argument, and the return value is an enumeration member or nil . You can use this initialization method to create a new enumeration variable.

This example creates an enumeration member from the original value 7 :

let possiblePlanet = Planet(rawValue: 7)// possiblePlanet 类型为 Planet? 值为 Planet.Uranus

However, not all possible Int values can be found for a matching planet. Because of this, the constructor can return an optional enumeration member. In the example above, possiblePlanet it is the Planet? type, or "optional Planet ".

Note: The original value constructor is a failed constructor, because not every original value has an enumeration member corresponding to it. For more information, see failed constructors

If you are trying to find a planet with a position of 9, the optional value returned by the parameter for the rawValue constructor Planet will be nil :

 let positiontofind = 9 if Let someplanet = Planet (rawvalue:positiontofind) {switch so meplanet {case. Earth: print ( "Mostly harmless") print ( "not a safe place for Humans")}} else {print (" there isn ' t a planet at position \ ( Positiontofind)}//output "there isn ' t a planet at position 9     

This example uses an optional binding (optional binding) to 9 attempt to access a planet by its original value. if let somePlanet = Planet(rawValue: 9)statement to obtain an optional Planet , if optional Planet can be obtained, set to somePlanet the optional Planet content. In this example, the location 9 of the planet cannot be retrieved, so the else branch is executed.

Recursive enumeration (Recursive enumerations)

When describing an operator, it is convenient to use an enumeration type to model the data, because it is a fixed enumerable to consider. The operator can concatenate two arithmetic expressions consisting of numbers, for example, to 5 concatenate into complex expressions 5+4 .

An important feature of arithmetic expressions is that expressions can be nested. For example, the expression (5 + 4) * 2 multiplication sign to the right is a number, and the left is another expression. Because the data is nested, the enumeration type used to store the data might support this nesting ———— this means that enumeration types need to support recursion.

递归枚举(recursive enumeration)is an enumeration type that represents the enumeration in which one or more enumeration members have other members of the enumeration as related values. When recursive enumeration is used, the compiler inserts a middle layer. You can add a member before enumeration indirect to indicate that the member is recursive.

For example, in the following example, an enumeration type stores a simple arithmetic expression:

enum ArithmeticExpression {    case Number(Int)    indirect case Addition(ArithmeticExpression, ArithmeticExpression)    indirect case Multiplication(ArithmeticExpression, ArithmeticExpression)}

You can also add a keyword at the beginning of an enumeration type indirect to indicate that all its members are recursive:

indirect enum ArithmeticExpression {    case Number(Int)    case Addition(ArithmeticExpression, ArithmeticExpression)    case Multiplication(ArithmeticExpression, ArithmeticExpression)}

The enumerated types defined above can store three arithmetic expressions: a pure number, an addition of two expressions, and a multiplication of two expressions. Addition Multiplication The values associated with the member are also arithmetic expressions ———— These related values make nested expressions possible.

Recursive functions can intuitively use data structures that have recursive properties. For example, here is a function that computes an arithmetic expression:

FuncEvaluate(expression:arithmeticexpression), Int {Switch Expression {Case. Number (LetValue):ReturnValueCase. Addition (let left, let right): return Evaluate (left) + evaluate (right) case. Multiplication (let left, let right): return Evaluate (left) * Evaluate (right)}} //calculation (5 + 4) * 2let five = Arithmeticexpression.number (5) let four = Arithmeticexpression.number ( 4) let sum = arithmeticexpression.addition (five, four) let Product = Arithmeticexpression.multiplication (sum, arithmeticexpression.number (2)) print (Evaluate (product)) //Output "" "            

If the function encounters a pure number, it returns the value of the number directly. If an addition or multiplication is encountered, the values of the left and right expressions are computed separately and then added or multiplied.

Swift Learning note-enumeration (enumerations)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.