The book "Swift. Basics of developing applications for iOS, iPadOS and macOS. 5th ed. supplemented and revised "

image Hello, habrozhiteli! Swift language is young, it grows, develops and changes, although the basic approaches to programming and development have already been formed. In the new, fifth edition of the book, the first part of the book was completely revised, which makes acquaintance with the Swift language more comfortable, and the entire text is updated in accordance with the capabilities of Swift 5. In the course of a long and fruitful communication with readers, many ideas appeared, thanks to which the new edition became even more useful and rich educational materials. Now you will not only learn Swift, but also get initial information about the principles of developing full-fledged applications. The world of Swift is constantly changing, people with a significant store of knowledge and experience do not yet exist because of the age of the language, so you can become one of the first specialists.



Excerpt. Chapter 6. Tuples



You may have never encountered such a concept as tuples in programming, however, this is one of the very useful features available in Swift. Tuples, for example, can be used to work with coordinates. Agree, it’s much more convenient to wield a construction (x, y, z) written in one variable than to create a separate variable for each coordinate axis.



6.1. Tuple basics



A tuple is an object that groups values ​​of various types within a single composite value.



Tuples are the easiest way Swift can combine values ​​of arbitrary types. Each individual value in the tuple may have its own data type, which does not depend on others in any way.



Motorcade literal



A tuple can be created using the tuple literal .



SYNTAX



(_1, _2, ..., _N)
      
      





• value: Any - the next value of an arbitrary data type, included in the tuple.



The tuple literal returns the value defined in it as a tuple. A literal is surrounded by parentheses and consists of a set of independent values, separated by commas. The number of elements can be arbitrary, but it is not recommended to use more than seven.


NOTE

Further along the text there will be a large number of Syntax blocks. They describe how the constructions in question can be used in real programs. Before proceeding to these blocks, it is necessary to describe the structure of this block, as well as the elements used.



The first line will always directly determine the syntax itself that describes the use of the construct in the program code. In this case, conditional elements can be used (for example, value_1, value_2 and value_N in the syntax above). Usually they are written in the form of text to understand their purpose.



Detailed descriptions of conditional elements may follow. In some cases, elements can be grouped (as in the syntax above, where instead of elements value_1, value_2, etc., an element value is described, the requirements of which apply to all elements with a given name).



After the name of the conditional element, its data type can be indicated. Moreover, if a specific value of a certain type (for example, string, numeric, logical, etc.) should be used as an element, then the type is separated by a colon (:). If, however, an expression can be used as an element (for example, a + b or r> 100), then the type will be indicated after the dash and right angle bracket representing the arrow (->). One can be defined (for example, Int), and many data types (for example, Int, String).



The syntax above uses Any as a pointer to a data type. Any stands for any data type. In the process of learning, you will encounter more and more types that can be specified in this syntax block.



A detailed description of the syntax, as well as an example of its use, can follow.

I advise you to bookmark this page so that if necessary

always come back here.
A tuple is stored in variables and constants in the same way as values ​​of fundamental data types.

SYNTAX



 let  = (_1, _2, ..., _N) var  = (_1, _2, ..., _N)
      
      





Declaring a variable and a constant and initializing it with a literal tuple consisting of N elements as a value. To write a tuple to a variable, you must use the var statement, and to write to a constant, you must use the let statement.
Consider the following example. We declare a constant and initialize it with a tuple consisting of three type elements: Int, String and Bool (Listing 6.1).

Listing 6.1

 let myProgramStatus = (200, "In Work", true) myProgramStatus // (.0 200, .1 "In Work", .2 true)
      
      





In this example, myProgramStatus is a constant that contains a tuple as a value that describes the status of a certain program and consists of three elements:





This tuple groups the values ​​of three different data types within a single, initialized constant.



Tuple data type



But if a tuple groups the values ​​of various data types into one, then what type of data is the tuple itself and the parameter that stores its value?



A tuple data type is a fixed, ordered sequence of data type names for tuple elements.

SYNTAX



 (____1, ____2, ..., ____N)
      
      





The data type is enclosed in parentheses, and element type names are separated by commas. The order of type names must necessarily correspond to the order of elements in the tuple.



Example



 (Int, Int, Double)
      
      





The data type of the myProgramStatus tuple from Listing 6.1 is (Int, String, Bool). The data type is implicitly set, as it is automatically determined based on the elements of the tuple. Since the order of specifying data types must match the order of the elements in the tuple, the type (Bool, String, Int) is different from (Int, String, Bool).



Listing 6.2 compares the data types of the various tuples.



Listing 6.2

 var tuple1 = (200, "In Work", true) var tuple2 = (true, "On Work", 200) print( type(of:tuple1) == type(of:tuple2) )
      
      





Console

 false
      
      





To compare the data types of tuples, the values ​​returned by the global function type (of :), which determines the type of the object passed to it, are used.

Suppose that in the myProgramStatus tuple, the first element should be a Float value instead of an integer. In this case, you can explicitly determine the data type of the tuple (a colon after the parameter name) (Listing 6.3).



Listing 6.3

 //       let floatStatus: (Float, String, Bool) = (200.2, "In Work", true) floatStatus // (.0 200.2, .1 “In Work”, .2 true)
      
      





You are not limited to any specific number of tuple elements. A tuple can contain as many elements as needed (but remember that it is not recommended to use more than seven elements). Listing 6.4 shows an example of creating a tuple of four elements of the same type. It uses an alias of the Int data type, which is not prohibited.



Listing 6.4

 //     Int typealias numberType = Int //       let numbersTuple: (Int, Int, numberType, numberType) = (0, 1, 2, 3) numbersTuple // (.0 0, .1 1, .2 2, .3 3)
      
      





6.2. Interaction with tuple elements



The tuple is intended not only for setting and storing a certain set of values, but also for interacting with these values. In this section, we discuss how to interact with the values ​​of the tuple elements.



Initialization of values ​​to parameters



You can declare new parameters with one expression and initialize the values ​​of all elements of the tuple in them. To do this, after the var keyword (or let, if you declare constants) in brackets and a comma, you must specify the names of the new parameters, and after the initialization operator, pass a tuple. Note that the number of declared parameters must match the number of tuple elements (Listing 6.5).



Listing 6.5

 //      var (statusCode, statusText, statusConnect) = myProgramStatus //   print("  — \(statusCode)") print("  — \(statusText)") print("   — \(statusConnect)")
      
      





Console:

 200In Worktrue
      
      





Using this syntax, you can easily initialize arbitrary values ​​to several parameters at once. To do this, on the right side of the expression, after the initialization operator, it is necessary to pass not the parameter containing the tuple, but the tuple literal (Listing 6.6).



Listing 6.6

 /*         */ var (myName, myAge) = ("", 140) //    print("  \(myName),   \(myAge) ")
      
      





Console:

   ,   140 
      
      





The variables myName and myAge are initialized with the corresponding values ​​of the tuple elements (Troll, 140). Using this syntax, you can ignore arbitrary tuple elements. To do this, you must specify the underscore character as the name of the variable corresponding to the element to be ignored (Listing 6.7).



Listing 6.7

 /*      */ var (statusCode, _, _) = myProgramStatus
      
      





As a result, the value of the first element of the tuple, myProgramStatus, is written to the statusCode variable. Other values ​​will be ignored.



NOTE

The underscore in Swift indicates ignoring the parameter. This is not the only example where it can be used. In the future, when studying the material of the book, you will meet with him more than once.


Access tuple elements through indexes



Each element of the tuple, in addition to the value, contains an integer index that can be used to access this element. Indexes are always in order, starting from zero. Thus, in a tuple of N elements, the index of the first element will be 0, and the last can be accessed using the index N-1.



When accessing a single element, the index is indicated through the dot after the name of the parameter in which the tuple is stored. Listing 6.8 shows an example of accessing the individual elements of a tuple.



Listing 6.8

 //      print("   — \(myProgramStatus.0)") print("   — \(myProgramStatus.1)") print("    — \(myProgramStatus.2)")
      
      





Console:

 200In Worktrue
      
      





Access tuple elements through names



In addition to the index, each element of the tuple can be assigned a unique name. Element names are not required and are used only for the convenience of using tuples. Names can be given to both everyone and parts of elements. The name of the element can be defined both in the literal of the tuple, and by explicitly defining its type.



Listing 6.9 shows an example of determining the names of tuple elements through a literal.



Listing 6.9

 let statusTuple = (statusCode: 200, statusText: "In Work", statusConnect: true)
      
      





The specified element names can be used to obtain the values ​​of these elements. In this case, the same syntax is used as when accessing through indexes, when the index was specified through the point after the parameter name. Defining names does not prevent you from using indexes. Indexes in a tuple can always be used.



Listing 6.10 shows how element names are used in conjunction with indexes.



Listing 6.10

 //      print("   — \(statusTuple.statusCode)") print("   — \(statusTuple.statusText)") print("    — \(statusTuple.2)")
      
      





Console:

 200In Worktrue
      
      





Access to elements using names is more convenient and visual than access through indexes.

As mentioned earlier, element names can be specified not only in the tuple literal, but also when explicitly determining the data type. Listing 6.11 shows the corresponding example.



Listing 6.11

 /*          */ let anotherStatusTuple: (statusCode: Int, statusText: String, statusConnect: Bool) = (200, "In Work", true) //    anotherStatusTuple.statusCode // 200
      
      





Tuple Editing



For tuples of the same type, the operation of initializing the value of one tuple into another can be performed. Consider the example in Listing 6.12.



Listing 6.12

 var myFirstTuple: (Int, String) = (0, "0") var mySecondTuple = (100, "") //       myFirstTuple = mySecondTuple myFirstTuple // (.0 100, .1 "")
      
      





The tuples myFirstTuple and mySecondTuple have the same data type, so the value of one can be initialized to another. The first type is set explicitly, and the second through the initialized value.

Indexes and names can be used to change the values ​​of individual elements in a tuple (Listing 6.13).



Listing 6.13

 //   var someTuple = (200, true) //     someTuple.0 = 404 someTuple.1 = false someTuple // (.0 404, .1 false)
      
      





Tuples are very widespread in Swift. For example, with their help, you can easily return not one but several values ​​from your function (we will get acquainted with functions a little later).



NOTE



Tuples do not allow the creation of complex data structures, their only purpose is to group a certain set of heterogeneous or similar parameters and transfer them to the desired location. To create complex structures, you must use the tools of object-oriented programming (OOP), and more specifically, classes or structures. We will get to know them later.


»More details on the book can be found on the publisher’s website

» Contents

» Excerpt



25% discount on coupons for Swatchers - Swift



Upon payment of the paper version of the book, an electronic book is sent by e-mail.



All Articles