Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Swift_Essential_Training.docx
Скачиваний:
7
Добавлен:
25.05.2015
Размер:
683.22 Кб
Скачать

2. Complex Types Сложные типы

Creating and using arrays Создание и использование массивов

- Вместо того чтобы постоянно работать с одиночными значениями, по одному, мы хотим, чтобы начать группировки несколько значений вместе в коллекции. Swift имеет два основных встроенных типов коллекций, массива и словарь. Более сложные структуры данных, безусловно, может быть достигнуто путем объединения двух дополнительных рамок, но массива и словарь являются частью языках Swift самостоятельно. Таким образом, это то, что мы рассмотрим в первую очередь. Хорошо поэтому сначала вверх, массивы, наиболее распространенный тип коллекция по любой язык программирования на планете, упорядоченный набор элементов.

Таким образом, есть несколько основных правил, прежде чем сделать один. Массивы начинаются с нуля у Свифта, как вы, наверное, ожидать от C под влиянием языка. Мы начинаем с индексом ноль, и мы идем вверх по одному. Далее, массивы вводятся в безопасности в Swift, то есть мы создаем массивы конкретных типов. Мы создаем массив целых чисел или массив строк или массив (Бус). Вы не смешивать и сочетать ваш массив элементов.Большим преимуществом является то, что вы всегда будете знать, что вы собираетесь получить, когда вы индекс в конкретной Array, потому что оно введено.

Это в отличие от типичного поведения в Objective-C, где массив NS может занимать каких-либо объекта в любом месте, и вы часто приходилось писать код, чтобы выяснить, или, по крайней мере, подтвердить, что то, что вы только что вытащил Массив является то, что вы думал, что это было. Мы не должны беспокоиться о том, что здесь. Одна вещь, вы могли бы быть интересно, быстры массивы динамические, они изменчивы, они изменяемые, или повторное значительную, независимо термин, который вы предпочитаете использовать. Это зависит от многого. Это просто сводится к, используете ли вы Var ключевое слово или пусть при объявлении массива.

Если вы использовали Var, Ваш массив переменной. Это изменчивый, изменчива. Вы можете добавить к нему, удалить из него, изменить элементы в любом положении. Если вы использовали Пусть Ваш массив неизменная константа. После того как вы для этого массива при условии, что начальное состояние, начальное значение х, это исправлено Вы не можете добавить к нему, и вы не можете изменить эти элементы. Итак, как мы можем сделать один? К (X-Курт 6), я создал новый файл детская площадка и вот простой формат. Я собираюсь сделать основной массив целых чисел и сделать его как константу. Таким образом, я обеспечиваю несколько начальные значения.

Там есть пара вещей происходит здесь. Одним из них является, я использую эти квадратные скобки, чтобы обеспечить этот разделенный запятыми список целых чисел. Это сокращение литерал массива формат у Свифта. Я мог бы также использовать эти квадратные скобки, чтобы создать массив строк, например. В этом случае, это переменная-массив, потому что я использую Var. В обоих случаях мы имеем вывод типа происходит здесь. Эти значения являются настолько очевидно Целые здесь, и они настолько очевидно строк здесь, типа как случайное. Мне не нужно аннотации типа, но не сделать ошибку, что мы получаем строго типизированный массив целых чисел, и сильно набрал массив строк.

Если попытаться сделать массив с различными типами в то же время, я иду, чтобы получить ошибку компиляции, которая в X-кода будет отображаться, как только это обнаружено. Таким образом, в то время как эти два массива были свои виды вывод, как с переменными, если бы я хотел, чтобы объявить массив, но я не могу или не хочу, чтобы незамедлительно предоставить значения для Свифт и, то я буду нужен, напечатанное аннотации. Итак, давайте скажем, я хочу, чтобы объявить переменную массив строк, но не дать ему некоторые начальные значения. Если я хочу, чтобы (бормотание) просто переменная, которая была строка, я хотел бы сделать что-то вроде этого.

Ароматы: String. Ароматизаторы имеет тип String. Это обычная переменная типа String. Мне нужно переменной, которая (SUB) набранный массив строк. Я просто окружают типа с квадратными скобками. Вот как мы объявляем тип массива. Мои Вар вкусов типа массив String. Теперь, я могу установить некоторые начальные значения для этого. Я могу использовать буквальный формате массива. Это собирается установить первые три элемента, чтобы эти строки. Когда приходит время, чтобы получить доступ к этим элементам, как и во многих языках, я могу использовать квадратные скобки с определенного индекса целого числа непосредственный доступ к элементам.

Первый аромат доступа к нулевой элемент массива, который расскажет мне ваниль. Я могу использовать тот же формат, если я хочу, чтобы изменить значение в этом месте. Это разрешается, потому что, опять же, это массив переменных я могу изменить каждый элемент в каждой точке индекса. Как это переменная, я могу добавить элементы в массив. Здесь я использую метод Append, чтобы добавить в конец массива. Опять же, это тип, поэтому я могу только добавить строк. Если я пытаюсь добавить целое, или бульона, или что-нибудь еще, что мы получим ошибку компиляции.

Сказав, что у Свифта, вы также можете использовать сокращения для плюс равна оператору Добавить новое элемент массива. Хотя это также равна также может быть использован для добавления номера или конкатенации строк вместе. Чтобы избежать путаницы, необходимо использовать квадратные скобки вокруг этого нового элемента, чтобы сделать его очень ясно, что, когда кто-то читает этот код, мы добавляем элемент массива. Мы не просто изменение одной переменной String. Однако, если вы хотите, чтобы вставить новый элемент, не в самом конце, не добавляя в конец массива, но в какой-то другой определенной позиции, то, что это метод установки в массив, который мы можем использовать, который принимает две части информации.

Во-первых, новое значение, которое мы хотим добавить. Во-вторых, позиция индекса. Какие ячейки вы хотите поставить это на? Я собираюсь поставить в три. Хотя, это будет жаловаться на это, потому что индекс должен быть записан в виде имени периметру в Свифт. У меня есть этот маленький флаг компиляции выскакивать. Если я нажимаю, что он скажет мне, что там отсутствует метка аргументом при индексе. Там даже исправить его, что X-код предложить, и я могу позволить ей сделать это. Я просто подчеркнуть, что и и либо щелкните по нему или нажмите кнопку RETURN. Она вставляет, что с именем Аргумент для меня.

Теперь, как мы начинаем иметь несколько элементов в этом массиве, хочу посмотреть, что свой нынешний статус. Я мог бы написать имя массива на это собственной линии, это хороший способ, чтобы увидеть его. Мы можем увидеть некоторые из этой информации, если бы я имел больший экран я был бы в состоянии видеть больше. Я могу масса снова и пусть он даст мне всплывающее окно. Другим вариантом является приехать и найти глазного яблока. Это значок быстрый взгляд. При нажатии, что он позволяет нам заглянуть внутрь более сложные объекты, которые не могут быть легко отображаются в панели результатов. В этом случае, чтобы показать нам, что наш массив выглядит, и мы можем нажмите на эту кнопку в каждой точке вдоль пути.

Подчеркивая быстрый взгляд здесь, у нас есть только три элемента. Подчеркивая здесь, у нас есть шесть. Если бы это было Массив объектов, мы получили бы дополнительно иконку быстрого заглянуть внутрь каждого элемента, который позволил бы нам развернуть еще дальше в них. Ладно, так что это добавление. Ну есть также возможность удалять элементы. Мы можем использовать удалить последний или удалить на методы индекса удалить элемент из массива. Один очень типичным требованием является, чтобы узнать, сколько элементов массива имеет.

В Свифт, это мы, используя свойство Count. Я буду использовать точечный синтаксис, чтобы добраться до этого. Так, печати, массив имеет как никогда много пунктов daysinmonth.count. Это массив, который я создал на вершине здесь, на третьей линии. За то, что сказал, что, если я проверки массив, который пуст, я мог проверить на счет нуля, но есть также встроенный пуст недвижимость в слитках, что я могу проверить, что делает код более читаемым. Так что, если DAYSINMONTH. пусто, у нас нет ничего в массиве.

Теперь, когда у нас есть коллекции, мы хотим быть в состоянии пройти через всю вещь для перебора каждого элемента. Мы могли бы, конечно, использовать стандартный стиль C цикл или время цикла, чтобы сделать эту Отслеживание индекса. Это гораздо проще в Swift использовать цикл для заезда. Мы даже не придется беспокоиться о индексов. Мы можем просто автоматически пройти через каждый элемент массива, однако много чего. Таким образом, общий формат делает, что это для отдельного элемента в какой-то коллекции. У нас есть массив коллекцию под названием DAYSINMONTH.

Итак, вот наше имя коллекции. Для каждого элемента, ну, это зависит от нас. Что мы хотим вызвать каждой отдельной части. Ну, я мог бы также нам имя, которое означает один индивидуальный элемент этого массива. Таким образом, я буду использовать месяц. Таким образом, для месяца в DAYSINMONTH, мы должны закрыть, что код скобки. Теперь, помните Массивы тесно в Swift, так что если я пишу для в цикл, который перебирает массив целых чисел, который, что я делаю здесь, то какое бы имя я использую здесь, в этом случае месяц, будут представлять каждый Int в массив по одному.

Если бы я писал для в цикл, который перебирает массив строк, то это имя будет представлять каждую строку в массиве. Это так. Вот и все, что нам нужно сделать, чтобы пройти через массив. Не беспокойтесь об индексах или столбы не стрелки, он просто работает. Я вижу здесь, что у нас есть 12 раз. Это показывает мне, что есть 12 пунктов данного массива. Таким образом, мы пошли через петлю 12 раз. Если бы я хотел видеть на самом деле произошло, я наведите курсор, чтобы кнопки историю значений на детской площадке, нажмите что. Это собирается открыть третий раздел, и мы будем видеть на выходе отсюда, как заявления для печати строки.

Первый аромат ванили.Массив имеет 12 пунктов, а затем каждый отдельный элемент печатается с этой петли, каждый на своей строке. Ладно, так что это основы работы с массивами. Действительно, за последние несколько минут не только был основной идеи работы с массивами, но основные идеи работы с любой коллекцией Свифт. Так, давайте некоторые из этих идей и увидеть другую встроенного типа Swift коллекции.

Using dictionaries

- And the second built-in collection type in Swift is the dictionary. Depending on your language background, you may be familiar with the concept of this collection using the term Associative Array, or with Map, or by Hashtable, or, possibly, just Dictionary. Swift certainly isn't the only language that calls this kind of data structure a dictionary. So, the key difference: while a basic array stores multiple values, each one accessed with a zero-based sequence of integers, a dictionary, instead, stores multiple values, each one accessed using a unique key.

So, with a dictionary, we store sets of keys and values, each one being a key/value pair, and the key/value pairs are kept together. This key could be a string, or the key could be an integer. In fact, the key can be any kind of object. Unlike an array, the keys in a dictionary do not have to be in any specific order, as long as they are unique. We can't have duplicate keys in a dictionary. We can have duplicate values, if that makes sense for your data, but we can't have duplicate keys.

This example is US state as values, accessed using their state abbreviations as keys. Or we might have airport codes as keys and their corresponding cities as values, or product IDs as keys and the products they represent as values, but always key and value pairs that belong together. Just as with arrays, dictionaries in Swift are strongly-typed. That's not just one type but two, because, for any one dictionary, all the keys must be of a specific type and all the values of a specific type, although the type of the keys and the type of the values don't have to be the same.

So we could, for example, as on the left here, we could have a dictionary where all the keys are integers and all the values are strings, or a dictionary where all the keys are strings and all the values are Booleans, or a dictionary where all the keys are strings and all the values are also strings. But what we can't have is one dictionary where the key might be an Int or might be a string. That is not permitted. Over to Xcode, I have a new blank playground here. When creating a dictionary, as when creating any variable or constant or array, we must provide some kind of type information.

We either use type inference and let Swift do it, if the initial values are obvious, or we'd have to use an explicit type annotation. So, first, the shorthand way to do it: with a simple dictionary, we can use a dictionary literal; looks very similar to the array literal in that it's using square brackets around the entire contents of this. But what we're doing is not just multiple single values, but multiple key and value pairs. Each key and value pair have a colon between them, and they're separated with a comma.

So here, what I'm doing is going to be using type inference. All the keys and all the values provided are obviously strings, so this array will be automatically typed as such. I can use Quick Look to see inside this dictionary, that it is four sets of key/value pairs, and drill down inside to see that each one has two pieces. However, if I wanted to declare a dictionary without any initial values, so there's nothing to infer, and then, later, load it up with values, perhaps some external data, I would need to declare it with a type annotation.

For a dictionary, it needs two types: the type of the keys and the type of the values. This is the way we do it. Here, I'm declaring a variable dictionary called products that is of type. We use the square brackets, Int, colon string, a dictionary with integer keys and string values. As with arrays, I can use the square brackets, the subscript syntax, if you prefer, to access any one key/value pair. If I do a printline statement, like this, in a dictionary using the key AZ -- so I'm printing whatever's found using that key -- I'll get the value Arizona, though, if you see it over here, in the results pane, it has the word 'optional' around it.

We'll get into optionals two movies from now, but, in short, it's because any time I'm accessing a dictionary, I have to keep in mind the idea that maybe this key is in the dictionary and maybe it isn't, and this line would have had nothing to print. I can also use this same format, using the subscript syntax to either change or to add a new value. So, in this case, I'm saying states and I'm using FL as a key. That doesn't actually exist in the initial values that I provided for this dictionary. So, in this case, what will happen is, because FL didn't exist, it'll be added as a new key/value pair.

If it did exist, it would have tried to change the value. Dictionaries in Swift don't have an append method like arrays do, simply because with arrays, we can always guarantee that we can add a new item to the end of an array. We just let the array decide what index that item is. But we're not letting the dictionary tell us what index we have; we're controlling the key. So with a dictionary, we need to support the idea that we think we're adding a new key/value pair, but that key might already exist in the dictionary with a different value for it.

Now, using this subscript syntax here is the shorthand format. The equivalent longhand method for doing this is the updateValue method, so updateValue forKey. So states is the name of our dictionary. Dot updateValue, we pass in a value, and then we name the parameter for a specific key. If the key exists, we'd update a corresponding value, but if it doesn't, it would be added as a new key/value pair. If I wrote this code in a playground, this call to updateValue, I would expect to see nil in the results pane because, what updateValue does is, attempt to first retrieve and return any original value for this key, if one existed in the dictionary before it then updates that value.

Well, in my case, this key NV did not exist, so we get nil returned, nil in Swift simply meaning the absence of a value. On the other hand, if I write the same code, doing a updateValue, but where the key actually matches, then I will get the existing value returned before it's then updated. So, in this case, I'm trying to change the value for the key KY. That does exist. That was in the original version of this dictionary up here on line three, and I'm updating the value, but this will first return the original value for this, which was just the word Kentucky.

Let's take a look at the current state of this dictionary. I'll just write it on its own line, come over here and, in the Quick Look, click the eyeball here, and we can see that this is pretty much the sets of keys and values I would expect to see right now. Notice that they do not have to be in any specific order here. You might have created things in alphabetical order, but the way things have been added, that does not need to be kept in that way. Well, we've seen a place where we're using this word nil, and that's an important word when we're working with dictionaries because, talking of nil, the easiest way to remove a key/value pair from a dictionary is to use subscript syntax, using a particular key and then setting its value to nil.

So we're finding the key DE and setting equal to nil. Now, importantly, this does not mean that the key DE still exists in the dictionary, just has a nil value. This will remove the entire key/value pair from the dictionary. Then, if I wanted to verify that, I could put the word of that state after, use Quick Look, and we do not have DE with an empty entry; it's completely gone. The equivalent longhand method for doing this would be called removeValueForKey.

Again, despite the name, this doesn't just remove the value, it removes the entire key/value pair from the dictionary. Though, this one will also return the original value that might have been at that key position, in this case, California. Now, as with arrays, we can use the dot countProperty to find out the number of key/value pairs in the dictionary. In this case, there will be four states left after adding some and removing some others. And, finally, with dictionaries, we'll also want to be able to iterate over it, to step through every item.

We can also use the convenient for in loop to go through every key/value pair in a dictionary. Although the syntax does have one extra touch, because the item that we get each time around doesn't just have one piece of information, it will have a couple. It will have both a key and a value. So here, I've got this for in loop: for, individual item, in the state collection. Now, we've got them written inside parentheses here, key, comma, value, but these are actually temporary names for each time around the loop, and these names are up to us.

It'll be the key, then the value, but I could have actually just as easily written abbrev, comma, fullname. Whatever the first one is will be the key; we'd have to use that within the body of the loop. Whatever the second one is will be the value. So this will loop through all the key/value pairs in states. Then we got this four times option here. I could click the plus button, the value history button, to see the output. And this is exactly what I'd expect. There are four states left, AZ is short for Arizona, et cetera, et cetera.

So we're iterating very easily over the entire dictionary and getting to both the key and the value. It's a very easy, readable format. However, this simple-looking piece of syntax here, where we have two names enclosed in parentheses, we need to talk about this, because it represents our first, but not our last, encounter with a concept found in Swift but not found in many other programming languages, and that's the idea of a "tupple," or tuple ... up next.

Using dictionaries Использование словарей

- А второй встроенный тип коллекции в Свифт словарь. В зависимости от вашего языка фоне, вы можете быть знакомы с концепцией этой коллекции, используя термин ассоциативный массив, или с картой, или по Hashtable, или, возможно, просто словарь. Swift, конечно, не единственный язык, который называет этот вид структуры данных словаря. Таким образом, ключевое отличие: в то время как базовую магазинов массива несколькими значениями, каждый из которых обращались с отсчетом от нуля последовательности целых чисел, словарь, вместо этого, хранит множество значений, каждое из которых доступны с помощью уникального ключа.

Таким образом, со словарем, мы храним наборы ключей и значений, каждое из них пару ключ / значение, и пар ключ / значение хранятся вместе. Этот ключ может быть строкой или ключ может быть целым числом. В самом деле, ключ может быть любой тип объекта. В отличие от массива, ключи в словаре не должны быть в любом определенном порядке, при условии, что они являются уникальными. Мы не можем иметь дубликаты ключей в словаре. Мы можем иметь одинаковые значения, если это имеет смысл для ваших данных, но мы не можем иметь дубликаты ключей.

Этот пример США, штат в качестве значений, получить с помощью своих государств сокращений в качестве ключей. Или мы могли бы иметь коды аэропортов в качестве ключей и соответствующие им города, как ценности, или идентификаторы продуктов в качестве ключей и продуктах, которые они представляют в качестве значений, но всегда ключей и значений пар, которые принадлежат друг другу. Так же, как с массивами, словари Swift сильно типизированных. Это не только один тип, но два, потому что по какой-либо один словарь, все ключи должны быть определенного типа, и все значения определенного типа, хотя тип клавиш и тип значений не должны то же самое.

Таким образом, мы могли бы, например, как на левой стороне здесь, мы могли бы иметь словарь, где все ключи целые числа, и все значения являются строками или словаре, где все ключи являются строками, и все значения Булевы или словаре где все ключи являются строками, и все значения также строки. Но то, что мы не можем иметь один словарь, в который ключ может быть Int или может быть строка. Это не допускается. К Xcode, у меня есть новый пустой площадка здесь. При создании словаря, как и при создании любой переменной или постоянной или массив, мы должны обеспечить какую-то информацию типа.

Мы либо использовать вывод типов и пусть Swift сделать это, если начальные значения очевидны, или мы должны были бы использовать явное аннотацию типа. Так, во-первых, сокращение способ сделать это: с помощью простой словарь, мы можем использовать словарь буквальное; очень похож на массив буквальном тем, что он использует квадратные скобки вокруг всего содержимого этого. Но то, что мы делаем это не только несколько отдельных значений, но несколько ключ и значение пар. Каждый ключ и значение пара есть двоеточие между ними, и они разделены запятой.

Так вот, то, что я делаю собираетесь использовать вывод типов. Все ключи и все допустимые значения, очевидно, строки, так что этот массив будет автоматически набирается как таковой. Я могу использовать Quick Look, чтобы видеть в этом словаре, что это четыре множества пар ключ / значение, и перейдите внутрь, чтобы увидеть, что каждый из них имеет две части. Тем не менее, если бы я хотел, чтобы объявить словарь без каких-либо начальных значений, так что нет ничего, чтобы сделать вывод, а затем, позже, загрузить его со значениями, возможно, каких-то внешних данных, я должен был бы объявить его с аннотации типа.

Для словаре, оно нуждается в двух типов: тип для ключей и тип значений. Это, как мы делаем это. Здесь я объявляю переменную словарь под названием продуктов, которые имеет типу. Мы используем квадратные скобки, INT, толстой кишки строк, словарей с целыми ключей и значений строк. Как с массивами, я могу использовать квадратные скобки, синтаксис индекс, если вы предпочитаете, чтобы получить доступ к любой паре один ключ / значение. Если я делаю Printline заявление, как это, в словаре с помощью ключа AZ - так что я печать все нашли с помощью этого ключа - я получу значение Аризона, хотя, если вы видите его здесь, в в панели результатов, то есть слово "дополнительный" вокруг него.

Мы войдем в опциями два фильма с этого момента, но, в общем, это потому, что в любое время я доступе словарь, я должен иметь в виду идею, что, может быть, этот ключ в словаре, и, может быть, это не так, и эта линия не имела бы никакого отношения к печати. Я могу также использовать этот же формат, используя синтаксис индекс либо изменить или добавить новое значение. Таким образом, в данном случае, я говорю, состояния, и я использую FL в качестве ключа. Это на самом деле не существуют в начальных значений, что я, предусмотренных для этого словаря. Таким образом, в данном случае, то, что будет происходить в том, потому что FL не существует, он будет добавлен в качестве новой пары ключ / значение.

Если все-таки существует, он попытался бы изменить значение. Словари у Свифта не имеют метод Append как массивы делают, просто потому, что с массивами, мы всегда можем гарантировать, что мы можем добавить новый элемент в конец массива. Мы просто дайте массив решить, что индекс, элемент. Но мы не давая словарь сказать нам, что индекс у нас есть; мы контроля ключ. Так со словарем, мы должны поддержать идею, что мы думаем, мы добавляем новую пару ключ / значение, но ключ может уже существовать в словаре с другим значением для него.

Теперь, используя этот синтаксис индекс здесь в коротком формате.Эквивалентный метод от руки этого является метод updateValue, так updateValue forKey. Так состояний название нашего словаря. Dot updateValue, мы передаем значение, а затем мы называем параметр для конкретного ключа. Если ключ существует, мы бы обновить соответствующее значение, но если это не так, он будет добавлен в качестве новой пары ключ / значение. Если бы я писал этот код в детской площадкой, этот призыв к updateValue, я ожидал увидеть ноль в панели результатов, потому что, то, что updateValue делает, попытка сначала загрузить и вернуть исходное значение для данного ключа, если таковой существовал в словаре прежде чем он обновляет это значение.

Ну, в моем случае, этот ключ NV не существует, поэтому мы получаем ноль вернулся, ноль у Свифта просто означает отсутствие значения. С другой стороны, если я пишу тот же код, делая updateValue, но где ключ на самом деле соответствует, то я получу существующее значение возвращается, прежде чем он обновляется. Таким образом, в данном случае, я пытаюсь изменить значение ключа Кентукки. Это действительно существует. Это было в оригинальной версии этого словаря здесь, на третьей линии, и я обновляю значение, но это будет первое возвращение в исходное значение для этого, который был просто слово Кентукки.

Давайте взглянем на текущее состояние этого словаря. Я просто написать его на своей собственной линии, иди сюда, а в Quick Look, нажмите глазное яблоко здесь, и мы видим, что это в значительной степени наборы ключей и значений, я бы ожидать увидеть прямо сейчас. Обратите внимание, что они не должны быть в любом определенном порядке здесь. Вы, возможно, создал вещи в алфавитном порядке, но способ, которым вещи были добавил, что не нужно быть таким образом. Ну, мы видели место, где мы используем это слово отсутствует, и это важное слово, когда мы работаем со словарями, потому что, говоря о нулю, самый простой способ, чтобы удалить пару ключ / значение из словаря для использовать синтаксис индекс, используя определенную клавишу, а затем установив его значение к нулю.

Таким образом, мы находим ключ DE и приравнивая к нулю. Теперь, главное, это не означает, что ключ ДЕ-прежнему существует в словаре, просто имеет нулевую ценность. Это позволит удалить пару весь ключ / значение из словаря. Затем, если бы я хотел, чтобы проверить, что я мог бы поставить слово этого государства после, используйте Quick Look, и мы не должны DE с пустой записи; это полностью исчез.Эквивалентный метод от руки для этого можно было бы назвать removeValueForKey.

Опять же, несмотря на название, это не просто удалить значение, он удаляет пару весь ключ / значение из словаря. Хотя, на этот раз также возвращает исходное значение, что, возможно, был в этой ключевой позиции, в данном случае, штат Калифорния. Теперь, как с массивами, мы можем использовать точечный countProperty, чтобы узнать количество пар ключ / значение в словаре. В этом случае, будет четыре состояния, оставшиеся после добавления и удаления некоторых некоторые другие. И, наконец, со словарями, мы также хотим, чтобы иметь возможность перебора него, чтобы пройти каждому пункту.

Мы также можем использовать удобный для в петлю, чтобы пройти через каждый пары ключ / значение в словаре. Хотя синтаксис имеет один дополнительный штрих, потому что элемент, который мы получаем каждый раз вокруг не просто один кусочек информации, она будет иметь пару. Это будет иметь как ключ и значение. Так вот, у меня есть это для цикла: для, отдельного элемента в государственной коллекции. Теперь, мы получили их пишется внутри скобки здесь, ключ, запятая, значение, но это на самом деле временные названия для каждого времени вокруг петли, и эти имена до нас.

Это будет ключевой, то значение, но я мог бы на самом деле так же легко, письменное расшифровать сокращение, запятая, FullName. Как бы то ни первый из них будет ключом; мы должны были бы использовать, что в теле цикла. Как бы то ни второй из них будет иметь значение. Так что это будет цикл через все пары ключ / значение в государствах. Тогда мы получили это четыре раза опцию здесь. Я мог бы нажать кнопку плюс, кнопку истории значений, чтобы увидеть результат. И это именно то, что я ожидал. Есть четыре государства оставили, AZ это сокращение от Аризоны, и так далее, и так далее.

Таким образом, мы итерации очень легко по всей словарь и получить как с ключа и значения. Это очень легко, легко читаемый формат. Однако эта простая на вид кусок синтаксиса здесь, где у нас есть два названия, заключенные в скобки, мы должны говорить об этом, потому что он представляет наш первый, но не последняя наша, встреча с концепцией нашли у Свифта, но не нашел во многих других языков программирования, и это идея "tupple", или кортежа ... в следующий раз.

Understanding tuples

- This term, like a lot in computing, originally comes from mathematics. Even the most math-phobic individuals should not be worried, it's an easy concept. A tuple or tuple is a group of elements a few values collected together, and that's all it means. Think of the terms double for two of something, triple for three, quadruple for four, quintuple for five, sextuple for six, septuple, octuple, et cetra. That's where this word tuple or tuple comes from. Sidebar, okay, I have to take a moment on pronunciation. You will hear this word pronounced as tuple, or as tuple, or indeed sometimes as tuple.

It seems to depend on when and where, including which side of the Atlantic you learned it in. Whether you first heard it in a programming situation or in a pure mathematics one. I first learned this word as tuple many years ago. If you prefer tuple or tuple, be my guest. I have no dog in this fight. Figure out how you would naturally say words like this, and pick your pronunciation accordingly. Tomato, tomato et cetra. End of sidebar, let's get back to Swift. A tuple is a quick and easy way to group values together.

Maybe two, maybe three, maybe four, maybe more them, and just pass them all around as a single item, without having to go to the formality of creating a struct, or a class, or loading these values into an array, or any other kind of formalized data structure. It is intentionally simple. All we do is gather the values we want, whether they are variables, or constants, or even just literal values, and put them in parenthesis separated by commas. So, over to X-code the new playground, if I had a couple of standard variables or constants, I could combine them into a tuple like this.

Just create a new variable, and put them inside parenthesis separated by commas. That's it. I've just made made a tuple. This variable named my tuple represents this single compound value, that itself contains two elements gathered together. I could do it with even more values. We can gather variables, constants, and literal values like this. So, a tuple can be multiple integer values, multiple Strings, or a miss-mash of different types, whatever you need at the time. Here's the thing, most of the time you won't actually need to make a tuple variable like I've done here.

You'll just use the parenthesis to gather some values together when it's useful to do so. In fact, our first tuple was when we were iterating through a (dictionary) just creating a simple dictionary here. We saw that when we were doing a for-in loop, when we do this, what we got each time around the loop is a tuple. It's a compound value that itself contains two pieces of information. So, here the abbreviation comma full name. This is a tuple. In this code I'm providing my own temporary name for each part of this, which I can then use inside the body of the (for it).

Doing this is called decomposing the tuple. We are accessing each inner element of that. Here's another example I'm going to us. When defining a function, we've all ready seen how to return a single value from a function, whether that's a String or an integer, whatever you need to do. You're just using the return arrow, and then naming the type. The information that you're returning. If I wanted to define a function that instead returns a tuple, returns multiple pieces of information combined into one, that's pretty simple to do as well.

We use the return arrow, and then we just put the types of the data that we want to return inside parenthesis separated by commas. So, instead of just returning a String, we now return a tuple that contains a String and an integer. We can return any kinds of data type in a tuple. We need to define those types in the order their in, so anyone calling this function will know what to expect. In my example here, I've just directly made a tuple in the return statement returning a String comma integer. Now, the question is, how do we call this? When we're calling this function, what do we do, what do we get, and how do we deal with it? Well, there's a couple of different options here.

I could do something like this. Calling the function and retrieving it into a new constant in this case. Let result equal whatever comes from get current song and duration. So, result will be the return tuple as a single compound value. I want to be able to get into that tuple to decompose it to get to the values that I know are inside it, the String and the integer. Say, if I wanted to just use it to write out a message, I have a couple of choices. So, I'm wanting to write out a message here, with the name of a song and its length.

Well, I know the tuple itself is called result. One of the options that I have is using an index number. You can think of the tuple as being a really simplistic array. I can use result.0 for the first part, and result.1 for the second. We pull those two pieces of information out of the tuple and show them in our print message. Well that works, but there's another more friendly option, is that up here where I'm finding the function that returns this tuple, I could actually provide a friendly name for each element in that.

So, before the String type, I'm going to say name:String and length:int. Now down here in the message, I'm retrieving result. That'll be the tuple, but it will have a name and a length property. So, I can say result.name, and that is result.length seconds long. Same information but a bit friendlier way to write it. As straight-forward as this is, there's even a simpler way to deal with the tuples that you get when you're calling a function.

So, let me comment out this code. What I'm going to show is, I'm going to call this function and decompose the tuple immediately, breaking it apart as I'm calling the function. Here's what I mean by that. Instead of the two steps of first retrieve the tuple with a specific name, and then use that name to break it apart, I simply do this. Create a new decompose tuple variable by calling this. I'm using the parenthesis to tell Swift that I fully expect a tuple return from this function call.

I don't care about naming the tuple itself, but these are the two names that I want to use for each inter element of that tuple. These names are whatever I want. They don't have to match anything written in the function definition. They do right now, but even if I hadn't had those defined in the function definition, this would work just fine. It's returns a String and an integer, I will call them name and length. I can use that information just to get directly to those parts of the tuple. The song is name, and its length seconds long.

Just double checking with the quick look, and we see the full message. Looks fine. That is the best intro to tuples that I can think of. They are very common in Swift. They're quick to create. They're quick and easy to use. It's important to understand tuples aren't intended to replace more formal data structures, they are simply a conveniently way to temporarily group a few values together. If the data you're grouping together actually belongs together, and you find yourself grouping the same data the same way in multiple places in your application, then you should probably be looking at a class or a structure, but we'll get to those a little later.

Understanding tuples Понимание кортежи

- Этот термин, как много в вычислительной техники, родом из математики. Даже самые Math-фобические люди не должны быть обеспокоены, это легко концепции.Кортежа или кортежей группа элементов несколько значений, собранных вместе, и это все, что это значит. Подумайте об условиях двойной для двух что-то, тройной для трех, четырехместные за четыре пятерки в течение пяти Шестиместный на шесть, семикратный, восьмикратный, и др CETRA. Вот где это слово кортежа или кортежей приходит. Боковая панель, ладно, я должен воспользоваться моментом, от произношения. Вы услышите это слово произносится как кортеж, или, как кортеж, или действительно иногда кортежа.

Это, кажется, зависит от того, когда и где, в том числе с какой стороны Атлантики вы узнали это. Если вы впервые услышали его в ситуации программирования или в чистой математике One. Я впервые узнал это слово как кортеж много лет назад. Если вы предпочитаете кортеж или кортеж, будь моим гостем. У меня нет собаки в этой борьбе. Выясните, как вы, естественно, сказать такие слова, как это, и выбрать свой произношение соответственно. Помидоры, помидоры и др CETRA. Конец боковой панели, давайте вернемся к Swift.Кортеж быстрый и простой способ для групповых ценностей вместе.

Может быть, два, ну три, может быть, четыре, а то и больше их, и просто передать их по всему качестве отдельного пункта, не прибегая к формальности создания структуры или класса, или загрузки этих значений в массиве, или любой другой вид формализованной структуры данных. Это нарочито простой. Все, что мы делаем, это собрать значения, которые мы хотим, являются ли они переменными или постоянными, или даже просто буквенные значения, и положить их в скобках через запятую. Таким образом, к X-кода новой детской площадке, если бы мне пришлось пару стандартных переменных или констант, я мог бы объединить их в кортеж, как это.

Просто создайте новую переменную, и поместить их в скобках через запятую. Это так. Я только что сделал сделал кортеж. Эта переменная назвал свой кортеж представляет этот единственный составное значение, что сам содержит два элемента, собранные вместе. Я мог бы сделать это с еще большим количеством значений. Мы можем собирать переменные, константы и символьные значения, как это. Таким образом, кортеж может быть несколько целых значений, несколько строк или Miss-пюре из различных типов, все, что нужно в данный момент. Вот вещь, большую часть времени вы не будете на самом деле нужно сделать переменную кортежа, как это сделал я.

Вы просто использовать скобки, чтобы собрать некоторые значения вместе, когда это полезно сделать. На самом деле, наш первый кортеж был, когда мы были переборе (словаря) просто создает простой словарь здесь. Мы видели, что, когда мы делали петлю для в, когда мы делаем это, что мы получили каждый раз вокруг петли кортеж. Это соединение значение, что само по себе содержит две части информации. Итак, вот аббревиатура запятой полное имя. Это кортеж. В этом коде я обеспечиваю свою собственную временное имя для каждой части этого, что я могу затем использовать внутри тела (для него).

Делая это называется разложением кортеж. Мы доступа к каждому внутренний элемент этого. Вот еще один пример, который я собираюсь к нам. При определении функции, мы все готовы увидеть, как вернуть одно значение из функции, будь Строка или число, все, что вы должны сделать. Вы просто используете обратный стрелку, а затем назвать тип.Информация, что вы возвращения. Если бы я хотел, чтобы определить функцию, которая вместо того, чтобы, возвращает кортеж, возвращает несколько частей информации, объединенных в один, это довольно просто сделать, как хорошо.

Мы используем обратный стрелку, а затем мы просто положить типы данных, которые мы хотим вернуться в скобках через запятую. Таким образом, вместо того, чтобы просто возвращает строку, мы теперь вернуть кортеж, который содержит строку и целое число. Мы можем вернуть все виды типа данных в кортеже. Нам необходимо определить те виды в порядке их в, так что любой вызов этой функции будет знать, чего ожидать. В моем примере здесь, я только непосредственно сделал кортеж в обратном заявлении возвращаются строки запятыми целое число. Теперь, вопрос в том, как мы называем это? Когда мы вызываем эту функцию, то, что мы делаем, что мы получаем, и как мы с ней боремся? Ну, есть несколько различных вариантов здесь.

Я мог бы сделать что-то вроде этого. Вызов функции и получение его в новой константе в этом случае. Пусть результат равный, что приходит от получения текущей песни и продолжительности. Таким образом, результат будет обратный набор как единое составное значение. Я хочу, чтобы иметь возможность попасть в эту кортежа разложить его, чтобы добраться до значений, которые я знаю внутри него, в строке и числом. Скажем, если бы я хотел, чтобы просто использовать его, чтобы написать сообщение, у меня есть несколько вариантов. Итак, я хотел, чтобы написать сообщение здесь, с именем песни и ее длины.

Ну, я знаю, сам кортеж называется результат. Один из вариантов, которые у меня есть, с помощью номера индекса. Вы можете думать о кортеже как быть действительно упрощенной массив. Я могу использовать result.0 для первой части, и result.1 для второго. Мы тянуть эти две части информации из кортежа и показать их в нашем послании печати. Ну, что работает, но есть другой, более дружественный вариант, является то, что здесь, где я нахожу функцию, которая возвращает этот кортеж, я мог фактически предоставить понятное имя для каждого элемента в этом.

Поэтому, прежде чем строкового типа, я собираюсь сказать Name: String и длина: Int. Теперь сюда в сообщении, я извлечения результата. Это будет кортеж, но она будет иметь имя и свойство длины. Таким образом, я могу сказать, result.name, и это долго result.length секунд. Ту же самую информацию, но немного дружественный способ, чтобы написать ее. Как прямо вперед, как это, есть даже более простой способ справиться с кортежей, которые вы получаете, когда вы вызываете функцию.

Итак, позвольте мне комментировать этот код. То, что я собираюсь показать, я буду называть эту функцию и немедленно разложить кортеж, разбив его на части, как я звоню функцию. Вот что я имею в виду, что. Вместо двух шагах сначала загрузить кортеж с конкретным именем, а затем использовать это имя, чтобы разбить его на части, я просто это сделать. Создать новую переменную разлагаются кортежа, называя такую. Я использую скобки сказать стремителен, что я полностью ожидать кортежа возвращения из этого вызова функции.

Я не забочусь о название самого кортеж, но эти два названия, которые я хочу использовать для каждого в том элемента этого кортежа. Эти имена, что я хочу. Они не должны совпадать, что написано в определении функции. Они делают прямо сейчас, но даже если у меня не было тех, которые определены в определении функции, то это будет прекрасно работать. Это возвращает строку и число, я назову их имя и длина. Я могу использовать эту информацию только, чтобы получить непосредственно в тех частях кортежа.Песня имя и долго ее длина секунд.

Просто дважды проверки с быстрым взглядом, и мы видим полное сообщение. Выглядит хорошо. Это лучший введение в наборах, что я могу думать. Они очень распространены у Свифта. Они быстро создать. Они быстры и просты в использовании. Важно понять, кортежи не предназначен для замены более формальные структуры данных, они просто удобно способ временно группа несколько значений вместе. Если данные вы группирования на самом деле принадлежит вместе, и вы окажетесь группировки и те же данные так же, как в нескольких местах вашего приложения, то вы, вероятно, следует искать в классе или структуре, но мы вернемся к тем,немного позже.

Creating optional variables

- Tuples aren't the only new thing in Swift. Another concept not found in many languages, including C and Objective-C, is that of optionals. Optionals let us describe a situation where sometimes we have a value and sometimes we don't. All right, let me unpack that statement, because there are some subtleties to this. If I declare a standard variable in Swift, without initializing it, without giving this a value, that's fine; I can do that. So here I'm saying I want an integer variable called temperature.

But this must be given a value before we use it. Swift does not default an integer variable to zero or default a string to an empty string, the way that some other languages do. And Swift will enforce the fact that a normal variable must be initialized before we attempt to use it. If I try to do any kind of operation on this, adding to it, printing it, I'm going to get an error telling me that this is not initialized and this is simply not allowed. So we've got this popping up over on the side, variable 'temperature' is used before being initialized.

We can't do this in Swift. All right, you might think, let's just go ahead and give this a basic initial value. I could just go ahead up here and give that an initial value of zero. I wouldn't even need the type annotation at that point. And that would make the error go away. But this is a bad idea for us in this case, and here is why: let's imagine that the value of this temperature variable is intended to be obtained by calling some function. It doesn't really matter what that function is, but let's say it's something that went out to the Internet and retrieved the current temperature and updated this variable.

But the problem is, sometimes we don't have a connection, so we can't get a value. We weren't able to get to the current temperature. We weren't able to update this variable. Well, in this case, I don't want this temperature variable to have a value of zero because zero is a valid temperature. It means it's wintertime and it's freezing. And there's a very big difference between saying, "Today's temperature is zero," versus saying, "We weren't able to obtain today's temperature." Data that's zero and data that's missing are two very different ideas.

So I'm going to go up here and remove that initial setting to zero, so that's bringing the error back here. So the situation that we have, we want to use optionals. Optionals allow us to say that, for any particular variable, we may have a value, and if we do, it will be of a particular type. It'll be an integer or a string or a Boolean. But we may have no value at all -- not zero, not empty string, not false ... nothing, or nil, the absence of a value. As we've seen, by default, variables are not allowed to have nil values; they're not allowed to be devoid of a value before they're being used.

By default, they must be initialized. So you have to choose to opt into these optionals, to support this on a variable-by-variable basis. So with this example, to support this idea that temperature might be nil, I would mark this temperature variable not as just an Int, but an optional Int. And I do that by adding a question mark immediately after the type, not even a space between them. So Int? here. And notice that the error has immediately gone away. Swift understands that this variable may be either an integer or it may be nil, nothing else.

Being optional doesn't mean it might be a string or might be a floater or might be a double. It's either going to be a valid Int or it's nil. And nil, as you can see, is what it's going to be considered first, because there's been no value assigned. And we're no longer getting an error. This is actually writing out the message, "The temperature is nil degrees." Well, this message isn't great. The thing is, if we're going to do this, we often don't need just the variable to support being an optional and having a nil value, we need to be able to test for that, as well.

So I had this message, but let's say that, before I write this message out, I need to test whether this does or does not have a value. So I can just ask, if temperature is not equal to nil, then we will do the print line and we should have some kind of temperature, and then close that ... (keyboard clicking) and we're fine. We have no error anymore. Having said that, right now we would never hit this line because the playground can tell that the value of temperature is nil. So let me fake this actually having a value, just to test that.

Temperature equals 65. Now we should count that temperature is not equal to nil, we should hit this printLine statement. And we do. What we get here is, "The temperature is Optional(65) degrees." I'm getting this extra text here. Because the temperature variable had its type changed from integer to optional integer, if I just have this basic code spitting out whatever the value of temperature is, it'll be wrapped up in that optional text, because it isn't a plain Int, it's an optional Int.

So if I don't want that extra optional text, what I need to do is, extract the value out of it. I need to add something to say that I know this is an optional variable, but I am positive it has a value and I just want that value. And to do that, I add an exclamation mark right after the use of the variable name, so not just temperature, but temperature!. This, again, is inside our backslash pair of parentheses, so it's using string interpolation to pull this value out.

What we're doing here is actually called forced unwrapping. We are forcing that optional variable, saying we know it has a value and pulling that value out. But we only ever do this if we are positive, if we are sure, that this optional actually does have a value. If you use the exclamation mark to forcibly unwrap an optional variable that is actually nil, you will get a run-time error. But, of course, we tested for this not being nil, so we're good. But it's not just your own code that you'll need optionals for.

We use optionals in many places in Swift. Here's one example: We've seen this dictionary example a couple of times. Multiple key/value pairs. Now, later on in my code, what I want to be able to do is, pull some value out of that dictionary. Var result equals, and I'm using NV as a way to try and pull information out. The thing is, this result variable, this new variable that I'm creating, will be automatically typed as a optional because this key may or may not exist in the dictionary.

So if it doesn't exist, we would want any result to be nil, and that's actually what we're getting because NV does not exist in the dictionary as a key. The playground can tell there is no NV key in the dictionary. Again, what we can do when dealing with optional values is, deal with them in two steps. We first try and retrieve a value, and then we will try and test to see if it is, or if it is not, equal to nil. We will deal with it. However, there's another option. We can kind of combine these two things into one step, so only dealing with values if they exist.

It's called optional binding. Now, this might look a little strange the first time you see it. Let me just comment out that old optional. We're still working with the dictionary here. Going to add a little code here. And this is the strange-looking part. We're using 'if let.' Well, really, what we're doing here is trying to say, we create a constant here. Let result equals states, and using NV to get to that key. But embedding that inside an if statement is going to try and do this thing called optional binding.

So we attempt to retrieve a value from the dictionary and put it in a constant called result. And the name is not important here. This is up to us. So if the key matches, then this constant will have a value. This if statement will be treated as true and we will drop in and print that state result out. But, on the other hand, if nothing was found for this key, we're just going to say, no, we don't have any match; in fact, this result variable, or rather, result constant, will not exist.

We will have nothing that we could write out even if we wanted to. Right now, because the playground understands the code that I've written, we are getting the "No matching key found," because it knows that NV doesn't exist. But if I change that to using a key that actually does exist, we should see the printLine statement will actually write out, "The state name is California." Now, one benefit of doing this optional binding option here, using if let, is that we do not need to forcibly unwrap the result that we get back. We don't need to use that exclamation mark after it, because it's already understood that there must be a value in this result constant because this counted as true.

Otherwise, it wouldn't even exist. So this is optionals. It's all about these question marks and exclamation marks that follow the variable. And we will see more of them as we go forward. One last thing to point out here: if you are an Objective-C user, know that optionals in Swift are not the same thing as nil pointers in Objective-C. In Swift, they are much more widespread, much more common. And, while in Objective-C, nil pointers were used to represent a nonexistent object, in Swift, any kind of value can be defined as optional, not just objects.

So as you read more and more Swift code, you will see a lot of these exclamation marks and question marks used to describe these situations, where we may or may not have a value, and after we understand that we may or may not have a value, we need to be able to extract that value out of the optional variables that we have.

Creating optional variables Создание дополнительных переменных

- Кортежи не только новая вещь у Свифта. Другая концепция не нашла на многих языках, в том числе С и Objective-C, является то, что дополнительными опциями. Дополнительное оборудование опишем ситуацию, когда иногда мы иметь значение, а иногда и мы не знаем. Ладно, дайте мне распаковать это заявление, потому что есть некоторые тонкости к этому. Если я заявляю, это стандартная переменная у Свифта, без его инициализации, не давая это значение, то это нормально; Я могу сделать это. Так вот, я говорю, что я хочу целочисленную переменную под названием температура.

Но это должно быть присвоено значение, прежде чем мы ее используем. Swift не по умолчанию целочисленную переменную к нулю или по умолчанию строку в пустую строку, так что некоторые другие языки делать. И Swift будет применять тот факт, что нормальная переменная должна быть инициализирована, прежде чем мы попытаемся использовать его. Если я пытаюсь сделать любой вид работы на этом, добавляя к нему, печати, я иду, чтобы получить ошибку, говорящую мне, что это не инициализирован, и это просто не пускают. Итак, мы получили этот выскакивают над на стороне, переменная «температура» используется до инициализации.

Мы не можем сделать это в Свифт. Ладно, вы думаете, давайте просто идти вперед и дать этому основной начальное значение. Я мог бы просто идти вперед здесь и дать, что начальное значение нуля. Я даже не нужно будет аннотации типа в этой точке. И, что бы сделать об ошибках. Но это плохая идея для нас в данном случае, и вот почему: давайте представим, что значение этой переменной температуры предназначен для позвонив по телефону некоторую функцию. Это действительно не имеет значения, что эта функция есть, но, скажем, это то, что вышел в Интернет и извлекать текущую температуру и обновили эту переменную.

Но проблема в том, иногда мы не имеем соединение, поэтому мы не можем получить значение. Мы не смогли добраться до текущей температуры. Мы не смогли обновить эту переменную. Ну, в данном случае, я не хочу эту переменную температуру, чтобы иметь нулевое значение, так как ноль действует температура. Это означает, что это зима и холодно. И есть очень большая разница между высказыванием, "Сегодня температура равна нулю", по сравнению с говоря, "Мы не смогли получить сегодняшнюю температуру." Данные, которые нулю, и данные, которые отсутствуют две очень разные идеи.

Так что я собираюсь пойти сюда и удалить этот начальную установку к нулю, так что привезет ошибку сюда. Так что ситуация, что мы имеем, мы хотим использовать УСТРОЙСТВА. Дополнительное оборудование позволяют нам сказать, что для любой конкретной переменной, мы можем иметь значение, и если мы это сделаем, это будет определенного типа. Это будет целое число или строка или Boolean. Но мы не может иметь никакого значения - не ноль, а не пустую строку, а не ложное ... ничего, или ноль, отсутствие значения. Как мы уже видели, по умолчанию, переменные не разрешено иметь нулевые значения; они не могут быть лишены значения, прежде чем они используются.

По умолчанию, они должны быть инициализированы. Таким образом, вы должны выбрать выбрать в этих дополнительных опций, чтобы поддержать это на переменном-на-переменная основе. Так что с этим, например, поддержать эту идею, что температура может быть ноль, я бы отметить эту переменную температуре не просто как Int, но по желанию Int. И я могу это сделать, добавив знак вопроса сразу после типа, даже не пространство между ними. Так Int? вот. И заметьте, что ошибка сразу ушел. Swift понимает, что эта переменная может быть либо целым или не может быть нулевой, ничего.

Будучи по желанию не означает, что может быть строкой или может быть поплавок или может быть в два раза. Это либо будет действителен Int или это ноль. И ноль, как вы можете видеть, то, что это не будет считаться первых, потому что там было не присвоенное значение. Не И мы больше не получаю сообщение об ошибке. Это на самом деле вывод сообщения ", температура равна нулю градусов." Ну, это сообщение не велика.Дело в том, если мы собираемся сделать это, мы часто нужна не просто переменную поддержку, по желанию и имеющие нулевую ценность, мы должны быть в состоянии проверить, что, как хорошо.

Так что мне пришлось это сообщение, но, скажем, что, прежде чем я пишу это сообщение, я должен проверить, является ли это делает или не имеет значения. Так что я могу только спросить, если температура не равна нулю, то мы сделаем печатать строку, и мы должны иметь какой-то температуре, а затем закройте это ... (щелчок клавиатуры), и мы хорошо. У нас нет ошибки больше. Сказав, что, прямо сейчас мы бы никогда не ударил эту линию, потому что площадка может сказать, что значение температуры равна нулю. Итак, позвольте мне подделка это на самом деле, имеющий значение, просто чтобы проверить это.

Температура равна 65. Теперь мы должны рассчитывать, что температура не равна нулю, мы должны ударить этого Printline заявление. И мы делаем. То, что мы сюда попасть ", температура не является обязательным (65) градусов." Я получаю дополнительный текст здесь. Потому что переменная температура была его тип изменяется от целого числа Необязательное целое, если я просто это основной код выплевывая все значение температуры, оно будет завернутый в том, что необязательный текст, потому что это не простой Int, это дополнительный Int.

Так что, если я не хочу, что дополнительный необязательный текст, что мне нужно сделать, это, извлечь выгоду из этого. Мне нужно что-то добавить, чтобы сказать, что я знаю, что это необязательно переменная, но я уверен, что имеет значение, и я просто хочу, чтобы значение. А для этого, я добавляю восклицательный знак сразу после использования имени переменной, так не только температура, но температура !. Это, опять же, в нашем обратной косой пары скобок, поэтому он использует интерполяции строк, чтобы вытащить эту величину из.

То, что мы делаем здесь, на самом деле называется вынуждены раскрутки. Мы заставляя что дополнительный переменную, говоря, что мы знаем, что это имеет значение и потянув это значение из. Но мы только когда-либо это сделать, если мы положительным, если мы уверены, что эта дополнительная действительно имеет значение. Если вы используете восклицательный знак принудительно развернуть дополнительный переменную, которая на самом деле отсутствует, вы получите ошибку времени выполнения. Но, конечно, мы протестировали для этого не будучи нулю, так что мы хорошо. Но это не только ваш собственный код, что вам нужно УСТРОЙСТВА для.

Мы используем УСТРОЙСТВА во многих местах в Свифт. Вот один из примеров: Мы видели этот словарь примере А пару раз. Несколько пар ключ / значение. Теперь, позже в своем коде, что я хочу быть в состоянии сделать это, потяните какую-то ценность из этого словаря. Результат Var равно, и я использую NV как способ попробовать и извлекать информацию из.Дело в том, эта переменная результат, это новая переменная, что я создания, будет автоматически набран так, как опция, потому что это ключ может или не может существовать в словаре.

Так что, если он не существует, мы хотели бы любой результат будет нулевой, и что на самом деле то, что мы получаем, потому что NV не существует в словаре в качестве ключа.Площадка могу сказать, нет ключа NV в словаре. Опять же, что мы можем сделать, когда речь идет дополнительных значений, бороться с ними в два этапа. Мы сначала попробовать и получить значение, а затем мы постараемся тест, чтобы увидеть, если он есть, или, если это не так, равен нулю. Мы будем иметь дело с ним. Однако, есть и другой вариант. Мы можем вид совместить эти две вещи в один шаг, так дело только со значениями, если они существуют.

Это называется дополнительный обязательный характер. Теперь, это может выглядеть немного странно в первый раз вы его видите. Позвольте мне просто комментарий, что старый необязательно. Мы все еще работаем со словарем здесь. Собираемся добавить немного кода здесь. И это странный часть. Мы используем », если позволить». Ну, на самом деле, то, что мы здесь делаем, это пытаемся сказать, мы создаем постоянной здесь. Пусть результат равен состояния и использования NV, чтобы добраться до этого ключа. Но вложения, что внутри, если заявление будет пытаться и делать то, что называется дополнительный обязательный характер.

Так мы пытаемся извлечь значение из словаря и положил его в постоянном называется результат. И имя не важно. Это зависит от нас. Так что, если ключевые матчи, то эта константа будет иметь значение. Это если заявление будет рассматриваться как истинное и мы будем опускать и распечатать которые заявляют о том привести из. Но, с другой стороны, если ничего не было найдено для этого ключа, мы только собираемся сказать, нет, мы не имеем ни одного матча; В самом деле, эта переменная результат, а точнее, в результате постоянной, не существует.

У нас не будет ничего, что мы могли бы написать, даже если бы мы хотели. Прямо сейчас, потому что площадка понимает код, который я написал, мы получаем "Нет соответствующих ключ не найден", потому что он знает, что NV не существует. Но, если я изменю, что с помощью ключа, на самом деле существует, мы должны увидеть Printline заявление будет на самом деле выписывают, "имя штатом является Калифорния." Теперь, одно из преимуществ делает этот дополнительный вариант переплета здесь, используя, если позволить, это то, что мы не должны насильно развернуть результат, который мы вернемся. Мы не должны использовать эту восклицательный знак после него, потому что он уже понял, что должен быть значение в этом результате постоянной, потому что это считается истинным.

В противном случае, он бы даже не существует. Так что это опциями. Это все об этих вопросительных знаков и восклицательных знаков, которые следуют переменную. И мы будем видеть больше из них, как мы идем вперед. Одна последняя вещь, чтобы отметить здесь: если вы пользователь Objective-C, знают, что опциями в Swift не то же самое, с нулевыми указателями в Objective-C. В Свифт, они гораздо более широкое распространение, гораздо более распространенным явлением. И, в то время как в Objective-C, ноль указатели были использованы для представления на несуществующий объект, в Swift, любой вид стоимости может быть определена как дополнительный, а не только объекты.

Так как вы читаете все больше и больше Swift код, вы увидите много этих восклицательных знаков и вопросительные знаки, используемые для описания таких ситуаций, где мы можем или не может иметь значение, и после того как мы понимаем, что мы можем иметь или не иметь значение, мы должны быть в состоянии извлечь это значение из дополнительных переменных, которые мы имеем.

Defining and using enumerations

- Sometimes it's useful to restrict our own options. Let's say I'm planning to build an airline booking application, and I want a variable called travelerSeatPreference, to say whether someone prefers window, middle, or an aisle seat. Now, if I define this as an Int, this will have a range of ... well, it's big. Compiled in a normal 64-bit machine, an Int has a range of two to the power of 64 minus one, which we might as well say is a range of several bazillion, kajillion possible values. But I want it to represent only window, middle, or aisle.

Now, sure, in my program, I could just give it a value of, say, two, and just keep it in my head that, in my application, zero should mean aisle and one should mean middle and two means window. But there's nothing that actually stops this variable from being changed to five or 73 or 385 million. Okay, it is true there are a few specialized integer types. After all, when I'm defining the type annotation up here and I type in Int, I will see not only Int but Int16, Int32, Int64, and even Int8 -- eight bits for smaller and smaller integers.

But even the smallest, the Int8, has 256 possible values. Now, it is true I could also store this as a string if I wanted to do that. And then I could just go ahead and give this a string value of window, but again, there's nothing really that would stop that from being set to all sorts of different values, and someone could change that to a traveler seat preference of 'banana,' and that would compile just fine. So we want to wait to define some data that has a more specific range of possible values.

And we have that with enumerations, or enums. Now, enumerations, of course, exist in many languages, but once again, in Swift, we do things similar to, but not exactly the same as, in other languages. To do this, what we'll do fist is, define the enum, define the possible values. If we want to have a variable that represents a seat preference, well, what possible values could that be? To set this up, we use the word enum, then the name of our new enumeration, and then a code block, the opening and closing curly brace.

Now, the style guideline here, because we are defining a new data type, not a new variable yet, is that we use an uppercase first letter for our new enumeration. In this case, I'm saying SeatPreference will be the new type. I want to be able to create variables or constants of the type SeatPreference, just as I can create variables or constants of type Int or type string. So inside these braces, I list the possible values that I want allowed. And you can use your own words here, whatever is meaningful to us.

In Swift, these are written as cases, similar to a switch daemon, so we are using the case keyword, although, in an enumeration, we don't need a colon. It's just case Window, case Middle, case Aisle, case NoPreference. So I'm adding this fourth option here, in case someone hasn't expressed a preference. I can write these as individual cases or, another alternative is, you actually can write them just on one line, just separated by commas: case Window, comma, Middle, comma, Aisle, comma, NoPreference. Personally, I find separate lines are more readable.

So each of these cases is referred to as a member, or a member value, of the enumeration. There's no limit to the amount of these. If I wanted 100 different member values in my enumeration, that's fine. It's my decision what's here, and the words are up to me. Again, these words are typically written with an uppercase first letter. This is not enforced, it is just accepted practice. Now, this is just preparation. What this all means after we're done is, we can use this new enumeration, SeatPreference, as a data type.

So I can create a new variable. I'll call it var jenPrefers. Start to type. We can get autocomplete here. SeatPreference, using the type annotation. So, a new variable called jenPrefers, of type SeatPreference. It now has a type, although it doesn't have a value. So I can add a value to this. jenPrefers equal to SeatPreference, dot, and it'll automatically show us that code complete dot Aisle, or Middle, or NoPreference, or Window. Let's just go ahead with Aisle.

This is a strongly-typed variable of type SeatPreference, and it has the value Aisle. Although, because this variable, jenPrefers, is already typed as a SeatPreference enumeration, I can, in Swift, use a shorthand format. I don't need to say SeatPreference. That's a little bit redundant. I can just say, dot Aisle or dot Middle or dot Window because Swift knows that the only possible values for this variable are SeatPreference member values. So I can just use this shorthand format.

But having said that, just like with other variables or constants, if I already know what value I want to set for a new variable or constant, I can just use type inference and do it all on one line, not two. So, create a new variable, royPrefers equals SeatPreference dot Window. And by providing a specific SeatPreference option, this will now be type-inferred as a SeatPreference with that specific value. The benefit of doing all this is not just that these are restricted to specific values, but also that, later on, in the code, I could do something like this.

We'll add a new switch statement on that new variable, and inside that, just do some cases. Now, these are cases within the switch statement, of course. Case dot Window, case dot Aisle, case dot Middle or case dot NoPreference. And the great thing is that the swift compiler will understand all the possible cases that this variable is allowed to be. Again, with a switch statement in Swift, I have to be exhaustive. But the compiler recognizes that I am being completely exhaustive here.

There are four possible options, and I'm checking them all so I don't even need a default case in this switch statement. Again, because the only options are SeatPreference options, this is strongly-typed as a SeatPreference variable. I can just say, case dot Window, case dot Aisle, case dot Middle, and so on. Now, here's the thing: even if you don't immediately want to write your own enumerations, you cannot avoid these. You will find that they're common in the Apple frameworks as a way to represent choices. And when you read through other people's Swift code or examples from Apple, you're likely to see many variables being set to a dot something value, or checked for a dot something value.

And that's the clue that this variable must be typed as some kind of enumeration. In Xcode, you can option-click a variable name to see what kind of enumeration it's defined at, but you will see this a lot. Enumerations in Swift are more powerful than in most languages, and they do go further than this. You can extend enumeration definitions to store internal values, you can even add properties and methods to add functionality, although, most of the time, what we've covered here is going to be all you need.

Defining and using enumerations

Определение и использование перечислений

- Иногда это полезно, чтобы ограничить свои варианты. Скажем, я планирую создать приложение-бронирования авиабилетов, и я хочу переменную travelerSeatPreference, чтобы сказать, предпочитает ли кто-то окно, в середине или в место прохода. Теперь, если я определяю это как Int, это будет иметь целый ряд ... ну, это большой. Составитель в обычном 64-битной машине, Int имеет ряд от двух до власти 64 минус один, который мы могли бы также сказать, от нескольких bazillion, kajillion возможных значений. Но я хочу, чтобы представлять только окна, в середине или в проход.

Теперь, конечно, в моей программе, я мог бы просто дать ему значение, скажем, два, и просто держать его в голове, что в моем приложении, нулевой должно означать проход и один должен означать средний и два средства окно. Но нет ничего, что на самом деле останавливается эту переменную от изменения до пяти или 73 или 385 000 000. Хорошо, это правда, есть несколько специализированных целые типы. В конце концов, когда я определяю тип аннотации здесь, и я типа в Int, я не только увидите Int, но Int16, Int32, Int64, и даже INT8 - восемь бит для меньших и меньших чисел.

Но даже самый маленький, INT8, имеет 256 возможных значений. Теперь, правда я мог хранить это в виде строки, если я хотел это сделать. И тогда я мог бы пойти дальше и дать этот строковое значение окна, но опять же, нет ничего действительно, что бы остановить это от того установлен на всякие разные ценности, и кто-то может измениться, что предпочтение путешественник посадочной 'банан, », и, собрать просто отлично. Поэтому мы хотим, чтобы ждать, чтобы определить некоторые данные, которые имеет более конкретный диапазон возможных значений.

И у нас есть, что с перечисления, или перечислений. Теперь, перечисления, конечно, существуют во многих языках, но опять же, у Свифта, мы делаем вещи, подобные, но не совсем такие же как в других языках. Чтобы сделать это, что мы будем делать кулак, определить перечисление, определить возможные значения. Если мы хотим иметь переменную, которая представляет предпочтение сиденья, ну что возможные значения это может быть? Чтобы установить это, мы используем слово перечисление, то имя нашего нового перечисления, а затем блок кода, открытие и закрытие фигурную скобку.

Теперь, стиль ориентиром здесь, потому что мы определяем новый тип данных, а не новая переменная тем не менее, является то, что мы используем заглавную первую букву для нашего нового перечисления. В этом случае, я говорю, SeatPreference будет новый тип. Я хочу, чтобы иметь возможность создавать переменные и константы типа SeatPreference, как я могу создать переменные или константы типа Int или типа строки. Так внутри этих скобок, я перечисляю возможные значения, что я хочу с животными. И вы можете использовать свои собственные слова здесь, что бы имеет смысл для нас.

В Свифт, они написаны как случаи, похожие на распределительном демона, так как мы используем случай ключевое слово, хотя в перечислении, мы не должны двоеточие. Это на всякий случай окно, дело Middle, дело Проход, дело NoPreference. Так я добавляю этот четвертый вариант здесь, в случае, если кто не выразил предпочтения. Я могу написать это в отдельных случаях или, еще одна альтернатива, вы на самом деле можете написать их только на одной строке, разделяя их запятыми: Случай окно, запятая, Middle, запятая, Проход, запятая, NoPreference. Лично я считаю, отдельные линии более читабельным.

Таким образом, каждый из этих случаев называются члена, или значение члена, перечисления. Там нет ограничения на количество из них. Если бы я хотел 100 различных значений членов в моем перечислении, это нормально. Это мое решение, что здесь, а слова до меня. Опять же, эти слова, как правило, написаны с заглавной первой буквы. Это не исполняется, он только что принял практику. Теперь, это только подготовка. Что все это означает, что после мы сделали это, мы можем использовать эту новую нумерацию, SeatPreference, как тип данных.

Так что я могу создать новую переменную. Я буду называть его VAR jenPrefers. Начните вводить. Мы можем получить автозаполнения здесь. SeatPreference, используя аннотацию типа. Таким образом, новая переменная называется jenPrefers, типа SeatPreference. В настоящее время она имеет тип, хотя это не имеет значения. Так что я могу добавить значение к этому. jenPrefers равные SeatPreference, точка, и она будет автоматически показывать нам, что полный код точек прохода, или в середине, или NoPreference, или окна. Давайте просто идти вперед с прохода.

Это сильно типизированных переменная типа SeatPreference, и это имеет значение прохода. Хотя, поскольку эта переменная, jenPrefers, уже ввели в SeatPreference перечисления, я могу, у Свифта, используйте сокращенный формат. Мне не нужно говорить SeatPreference. Это немного излишним. Я могу только сказать точек проходу или точка Средний или точка окно, потому что Свифт знает, что единственными возможными значениями для этой переменной являются значения членов SeatPreference. Так что я могу просто использовать эту коротком формате.

Но, говорит, что, как и с другими переменными или константами, если я уже знаю, какое значение я хочу установить для новой переменной или константы, я могу просто использовать вывод типов и все это на одной линии, а не два. Таким образом, создать новую переменную, royPrefers равно SeatPreference точка окна. И, предоставляя конкретный вариант SeatPreference, это теперь будет типа вывод как SeatPreference с этим конкретным значением.Преимущество делает все это не просто, что они ограничены конкретными значениями, но также, что позже, в коде, я мог бы сделать что-то вроде этого.

Мы будем добавлять новое заявление включите этой новой переменной, а внутри, что просто сделать некоторые случаи. Теперь, эти случаи в рамках Переключатель, конечно. Дело точка окна, дело точка прохода, дело точка Среднего или случае точка NoPreference. И что замечательно быстрым компилятор поймет все возможные случаи, что эта переменная имеет право быть. Опять же, с Переключатель в Swift, я должен быть исчерпывающим. Но компилятор признает, что я являюсь полностью исчерпывающим здесь.

Есть четыре возможных варианта, и я проверяю их все, так что я даже не нужно вариант по умолчанию в этом Переключатель. Опять же, потому что только варианты SeatPreference вариантов, это строго типизированный качестве переменной SeatPreference. Я могу только сказать случай точка окна, дело точка прохода, дело точка посередине, и так далее. Теперь, вот вещь: даже если вы не хотите сразу писать свои собственные перечисления, вы не можете избежать их. Вы увидите, что они распространены в рамках Apple, как способ представления выбора. И когда вы читаете чужие SWIFT-код или примеры из Apple, вы, вероятно, увидите много переменных, установленным на точечной что-то значение, или проверить на точечной что-то значение.

И это признак того, что эта переменная должна быть набраны как своего рода перечисления. В Xcode, вы можете опция кнопкой мыши имя переменной, чтобы увидеть, какие перечисления она была определена на, но вы увидите это много. Перечисления в Swift являются более мощными, чем в большинстве языков, и они идут дальше, чем это. Вы можете расширить определения перечисления для хранения внутренних значений, вы даже можете добавить свойства и методы для добавления функциональности, хотя, в большинстве случаев, что мы рассмотрели здесь будет все, что вам нужно.

Writing closures

- In Swift, we use closures to group codes together into reusable self-contained units. Now you might first hear that description and then think, "hang on, isn't "that what we do with a function?" "After all, a function groups some code "into a reusable self-contained unit." And yes, absolutely, in fact functions are a specialized type of closure. A function is a way to group some code together and give it a name. But a closure doesn't even need a name. It's actually simpler than a function. And other languages support this concept and call this idea an anonymous function.

Some other languages call it a lambda or in Objective C it's called a block. It's a way of being able to group some code together so we can pass it around from one place to another place in our application. And the great thing is, you already know how to get started with this. If you can write a basic function, you can write a closure. Here's what I mean, we already know how to create a simple function, so here's a function that takes no parameters and returns no values, it just performs a println statement.

Now if I were to just go ahead and remove the keyword "func" and the function name, this would be about the simplest closure in the world. Having said that, written by itself, this would cause Swift to throw an error. It's going to say that this is a braced block of statements that's an unused closure. It's basically saying, "yes, you're "grouping some code together, you're "writing this code block, but you're not "doing anything with it and you can't do "anything with this right now, so what's the point?" Because just as the point of writing a function is so you can call that function by using the function name, the point of writing a closure is that you have a block of code that you're going to pass around and use.

Now one way, not a very useful way, but one way I could get ready to do this, to pass this closure around is I could just store it in a variable or constant, just give it a name. So "let myClosure" or "var myClosure equals" and give it a code block. This would be giving this closure a name existing as a named piece of data, a named block of code. This probably doesn't seem to save much over having a function, but bear with me, we're taking this step by step. So, I have this closure to find and give it a name.

I'll now create a function that accepts a closure as a parameter and this is really the entire point of using closures, that we can create these blocks of code and pass them around into other parts of our program. So this is a regular function, we're just using the keyword "func," I've called it "performFiveTimes" and it accepts one parameter, which I've called "myClosureParameter." Now the only thing that should look a little weird right now is most of our parameters up to this point have been using the colon int or colon string or colon Boole.

Well this one's "colon empty parentheses "return arrow empty parentheses." Well, we will talk about this format in just a second, but this is how I'm saying that this function accepts a closure as a parameter, not an int, not a string, not something simple, but a block of code. So, within the function I have a simple loop that just goes around five times and each time, it's going to take whatever closure, whatever block of code that was passed in and execute it. Well, the point of defining a function is we're going to call it, so I can go ahead and call this function passing in the name of that closure that I named up here on line three called "myClosure" and it's going to pass it in to the function, it will loop around five times, calling that every time.

You can actually see the result of it up here that yes it will go through, it will give us console output and write that out five times. So here's the last thing, I can forget about this extra step of actually naming this closure. We can get rid of that, we can grab the closure itself, which is the opening and closing curly brace and any code in between, whether that's one statement like it is here or three or ten or 100 if necessary. And I'm just going to come down here on the function call and paste that entire thing right inside the parentheses as a block of code.

And this is the usual way that you will interact with these, if a function has been defined to accept a closure, to accept a block of code, you'll just directly type the curly braces inside the call to that function and paste in the contents of the code that you want to pass into the function. This works exactly the same way, we can see over here it's being executed five times, we can see the results of it coming out five times. But, there are a couple more things worth knowing about this format. See just as a function is a block of code that can take parameters as input and return values as output.

So can a closure, a closure can have parameters and return values. So let's compare them to function because that's probably the most useful comparison here. So I've got a simple function defined to take no parameters, it's got the empty parentheses after the function name. And we can assume it returns no values because we haven't specified any, there's no return arrow, there's no return arrow string or return arrow int. If I wanted to be very explicit that this function returns nothing, I can in Swift actually write this code, I could write it this way.

Empty parentheses for the input parameters and empty parentheses after the return arrow. And this is the format that we use when we're defining parameters and return type for a closure. So if we begin with a simple closure, the most straightforward code block in the world, simple closure that takes no parameters and returns no values, if we want to be explicit about it, we would take that same format and paste it inside the opening curly brace. Because whereas, with the function definition, we put parameters and return type information before the opening curly brace when we're working with a closure, there isn't anything before the opening curly brace.

A closure begins at the opening curly brace, so we put that information inside. So this is a closure that explicitly takes no parameters and returns no values. It just does a little bit of work. Now one last piece of official syntax is then to separate the parameter and return type information from the rest of the statements in the closure, we use the keyword "in" to split the two apart. Alright, back to the code. So, to revisit this function definition, this is what that syntax means, it's how we define the type for a function that is accepting a closure as a parameter and explicitly a closure that takes no parameters and returns no values, it just performs some action.

So if I pass in any closure matching that definition, it will do that work five times. However, I should really for best practice be explicit down here when I'm passing in that closure and say, "yes, "this is a closure that takes no "parameters, returns no values, "that's that piece of information here." And then I'd use the keyword "in" to separate the parameter and return information from the actual blocks of code from the code in the rest of our closure. And this doesn't change what it was doing a moment ago, but it's the more formal syntax for doing this and it's something that's worth being able to recognize.

So this begs the question, if we have closures that can take parameters and can have return types, how do they work, how do we use them? Well, to illustrate that, let me run through an example of using a closure with some existing functionality that's already in Swift and really, this is the big benefit of using closures, is they allow you to tap into an enormous amount of existing functionality. So, I'm just going to create a new playground. I can strip all the code out of this, as I really don't need it right now. And what we're going to do is use a piece of functionality that already exists, it's a function called "sorted." And there's a couple of ways this can be called, but one of the basic ways is to call it "sorted," passing in two pieces of information.

An array or another collection that you want to sort, and then a little bit of information, a closure, a little bit of code, a little bit of logic that says how any two elements in this array or in this collection should be compared. You see, this built-in sorted function can take care of sorting arrays of thousands of elements, you don't have to write an actual sort algorithm as long as you can provide a little bit of code, a little bit of logic that just says "how do you compare any two pieces?" So, first we create an array.

Now, for time's sake, I'm just using integers. More likely in this situation, it would be an array of some kind of custom object. So this sorted function wants to be provided with a closure that will take two parameters. Now for us, that will be two integers out of this array to compare. And it expects to get back a Boole. How do I know this? Well, I looked at the documentation for the sorted function. So, I need a closure that accepts two integers and returns either "true" if the first is less than the second, or "false" if otherwise. Now, if it seems tough to think, "well, how "would you begin writing that as a closure?" Well, the easy way to do it is first you write that as a regular function and then you change it to a closure, because that's much easier.

So, if we go ahead and write that as a regular function, I'd call it "compareTwo" and this takes two parameters in, they're both integers, I'll call them first and second, and it returns a Boole. I've made a typo there, I've said function instead of func. Let's get rid of that. and I'm using the shorthand method here, that's just going to directly return a Boolean comparison between the two, so if first less than second, we will return true. If anything other than that, we're going to return false. So, a very simple bit of code here, but it should do the trick.

We will convert this from a function into a closure in just a second. Now below this, we're going to have the call to the built-in sorted function and that's just available anywhere in Swift. sorted will return a sorted version of your collection, a sorted version of an array or a dictionary, so I'll create a new constant to retrieve the results into and we will call sorted. First piece of information to pass in is our unsorted array that I created on line five. Then a comma and then we need the closure.

So, I'm going to convert this function into a closure. First thing I'm going to do is just, actually, comment it out because I don't want Swift to be complaining about it with everything that I do here. So, how do we do this? Well, first I get rid of func and the function name, don't need that. Then, the curly braces needs to move right to the start because a closure opens with curly braces. So we have the opening curly brace, we have the parameter information and the return type information. Then we have the body of the closure. The only last thing I need to do is separate that with an in word here.

And that should work as our closure. And we just uncomment that, of course we don't need it by itself. I need to cut it, paste it after that and make sure to finish the closing parentheses for the sorted call. And it looks like it needed to do some kind of 37 comparisons in its compares, it's probably doing some kind of bubble sort, it doesn't really matter I don't care that much. What I'm interested in is the result, so I'm going to type the name of the sorted array down here and then just go over it and find the quick look icon and we can see that yes, we began with a randomly unsorted array and now it's one, two, three, four, 23, 98, it looks perfect, it looks in the right amount and the right structure.

And really, this is just a very quick example of the benefit of getting familiar with closures. Then, once you understand how to use them, you can tap into huge amounts of functionality throughout the Apple frameworks. Not just with sorting, but with networking code and concurrency and animation, there are a lot of pieces of functionality that have been defined for you to provide just a little bit of extra logic and you do that by providing closures. They all expect a familiarity with this idea and your life is so much easier when you have that.

Writing closures Написание закрытия

- В Свифт, мы используем закрытия в групповых кодов вместе в многоразовых автономных единиц. Теперь вы можете сначала услышать, что описание, а затем думать, "подожди, не является", что мы делаем с функцией "?" В конце концов, функциональные группы некоторый код "в многоразовой автономное устройство." И да, абсолютно, на самом деле функции специализированный тип закрытия.Функция способ группы некоторый код вместе и дать ему имя. Но закрытие даже не нужно имя. Это на самом деле проще, чем функции. И другие языки поддерживают эту концепцию и называют эту идею анонимную функцию.

Некоторые другие языки называют это лямбда или в Objective-C это называется блок. Это способ быть в состоянии группе некоторый код вместе, чтобы мы могли передать его из одного места в другое место в нашем приложении. И великое дело, вы уже знаете, как начать с этого. Если вы можете написать простую функцию, вы можете написать замыкание. Вот что я имею в виду, мы уже знаем, как создать простую функцию, так вот функция, которая не принимает никаких параметров и не возвращает значения, он просто не выполняет Println заявление.

Теперь, если бы я просто идти вперед и удалить ключевое слово "Func" и имя функции, это будет о простом закрытии в мире. Сказав, что написано само по себе, это может вызвать Swift вызовет ошибку. Это будет сказать, что это приготовился блок операторов, что это не используется закрытие. Это в основном говорят, "да, вы" группировки код вместе, вы "писать этот код блок, но вы не" делать что-либо с ним, и вы не можете сделать "что-нибудь с этим прямо сейчас, так чтосмысл? "Потому что так же, как точки написав функцию так можно назвать эту функцию, используя имя функции, смысл писать замыкание, что у вас есть блок кода, который вы собираетесь пройти вокруг и использовать.

Теперь в одну сторону, и не очень полезный способ, но так я мог получить готовы сделать это, чтобы пройти этот закрытие вокруг я мог бы просто сохранить его в переменной или константе, просто дать ему имя. Таким образом, "пусть myClosure" или "Var myClosure равных" и дать ему блок кода. Это будет давать это замыкание имя существующего как им части данных, как блоком кода. Это, вероятно, кажется, не значительно сэкономить над иметь функцию, но медведь со мной, мы берем это шаг за шагом. Так, у меня есть это замыкание, чтобы найти и дать ему имя.

Теперь я создам функцию, которая принимает замыкание в качестве параметра, и это действительно весь смысл использования замыкания, что мы можем создать эти блоки кода и передавать их вокруг в других частях нашей программы. Так что это обычная функция, мы просто с помощью ключевого слова "Func", я назвал его "performFiveTimes" и он принимает один параметр, который я назвал "myClosureParameter." Теперь единственное, что должно выглядеть немного странно прямо сейчас большинство наших параметров до этого момента были с помощью Int толстой кишки или толстой кишки строку или толстой кишки Буль.

Ну это своего "толстой кишки пустые скобки" возвращение стрелки пустые скобки. "Ну, мы будем говорить о таком формате всего за секунду, но это, как я говорю, что эта функция принимает замыкание в качестве параметра, а не INT, а нестрока, а не что-то простое, но блок кода. Таким образом, в функции у меня есть простой цикл, который просто идет вокруг пять раз и каждый раз, это будет принимать все прений, независимо блок кода, который был принят в и выполнить это. Ну, точка определения функции том, что мы собираемся называть его, так что я могу идти вперед и вызывать эту функцию передается имя этого закрытия, что я назвал здесь, на третьей линии под названием "myClosure", и это будет передать его в функцию, она будет петля вокруг пяти раз, называя, что каждый раз.

Вы можете увидеть результат его здесь, что да он будет идти до конца, это даст нам консольный вывод и пишут, что пять раз. Так вот последнее, что я могу забыть об этом дополнительном этапе фактически назвав это закрытие. Мы можем избавиться от этого, мы можем захватить само замыкание, которое открытие и закрытие фигурная скобка и любой код между ними, является ли это одно заявление, как это здесь, три или десять или 100, если это необходимо. И я просто хочу, чтобы приехать сюда по вызову функции и вставьте этот всю вещь прямо внутри скобок как блока кода.

И это обычный способ, что вы будете взаимодействовать с ними, если функция определена, чтобы принять замыкание, принять блок кода, вы просто напрямую введите фигурные скобки внутри вызова этой функции и вставить в содержание код, который вы хотели бы передать в функцию. Это работает точно так же, как мы видим, здесь он выполняется пять раз, мы видим результаты этого выходит пять раз. Но, есть ещё парочка вещей, стоит знать об этом формате. Смотрите, как функция блок кода, который может принимать параметры в качестве входных данных и возвращать значения на выходе.

Так может закрытие, закрытие может иметь параметры и возвращать значения. Итак, давайте сравним их работать, потому что это, вероятно, наиболее полезным сравнение здесь. Так что я получил простую функцию, не определенный предпринимать никаких параметров, он получил пустые скобки после имени функции. И мы можем предположить, что это не возвращает значения, потому что мы не указали, нет возврата стрелки, нет возврата стрелки строка или вернуться стрелкой Int. Если бы я хотел быть очень четко, что эта функция не возвращает ничего, я могу в Swift на самом деле писать этот код, я мог бы написать это так.

Пустые скобки для входных параметров и пустых скобках после возвращения стрелки. И это формат, который мы используем, когда мы определяем параметры и тип возвращаемого значения для закрытия. Так что, если мы начнем с простого закрытия, наиболее простой блок кода в мире, просто закрытия, которая не принимает никаких параметров и не возвращает значений, если мы хотим быть открытыми об этом, мы бы тот же формат и вставьте его в отверстие фигурная скобка. Потому что в то время как с определением функции, мы ставим параметры и вернуться в информации о типе перед открывающей фигурной скобкой, когда мы работаем с закрытием, нет ничего перед открывающей фигурной скобкой.

Закрытие начинается в открывающей фигурной скобкой, поэтому мы поместили эту информацию внутри. Так что это закрытие, которые явно не принимает никаких параметров и не возвращает никаких значений. Он просто делает немного работы. Теперь один последний кусок официального синтаксиса затем отделить параметр и возвращает информацию типа от остальной части заявления к закрытию, мы используем ключевое слово "в", чтобы разделить две части. Хорошо, вернемся к коду. Таким образом, чтобы вернуться к этому определение функции, это то, что означает, что синтаксис, это, как мы определяем тип для функции, которая принимает замыкание в качестве параметра и явно замыкание, не принимает никаких параметров и не возвращает никаких значений, он просто выполняет некоторые действия ,

Так что, если я прохожу в любом закрытия соответствие этому определению, он будет делать эту работу пять раз. Тем не менее, я должен на самом деле для лучшей практики быть явным сюда, когда я передаю в этом закрытия и сказать: "да", это закрытие, который не принимает "параметры, не возвращает никаких значений" Это та часть информации здесь ". а потом я хотел бы использовать ключевое слово "в", чтобы отделить параметр и возвращает информацию от фактических блоков кода из кода в остальной части нашей закрытия. и это не меняет того, что он делал минуту назад, но этоболее формальный синтаксис для этого, и это то, что стоит в состоянии признать.

Так возникает вопрос, если у нас есть закрытие, которые могут принимать параметры и может иметь возвращаемых типов, как они работают, как мы используем их? Ну, чтобы показать, что, позвольте мне работать через примера использования замыкание с какой-то существующей функциональности, которая уже у Свифта и действительно, это большая выгода от использования замыкания, именно они позволяют задействовать огромное количество существующей функциональности. Таким образом, я просто хочу, чтобы создать новую спортивную площадку. Я могу лишить весь код из этого, как я действительно не нужно это прямо сейчас. И то, что мы собираемся сделать, это использовать часть функциональности, которая уже существует, это функция, называемая "сортируются". И есть несколько способов это можно назвать, но один из основных способов является назовите его "сортировать", проходящей на две части информации.

Массив или другая коллекция, что вы хотите отсортировать, а затем немного информации, закрытие, немного кода, немного логики, говорит, как любые два элемента в этом массиве или в этой коллекции должны быть сопоставлены. Вы видите, это встроенный в отсортированном функция может заботиться о сортировке массивов тысяч элементов, вы не должны написать сам алгоритм сортировки до тех пор, как вы можете предоставить немного кода, немного логики, просто говорит: "как вы сравнить любые два куска?" Итак, сначала мы создаем массив.

Теперь, ради Время, я буду только с помощью целых чисел. Скорее в этом случае, это будет массив какой-то пользовательский объект. Таким образом, это отсортированный функции хочет быть снабжен закрытия, которая будет принимать два параметра. Теперь для нас, что будет два целых числа из массива для сравнения. И он рассчитывает получить обратно Буля. Как я знаю это? Ну, я посмотрел на документацию для отсортированного функции. Таким образом, мне нужно замыкание, которое принимает два целых числа и возвращает либо "истинно", если первый меньше, чем второй, или "ложь" в противном случае. Теперь, если вам кажется, трудно думать: "Ну, как" вы начинаете писать, что в закрытии? "Ну, простой способ сделать это сначала написать, что в регулярной функции, а затем изменить его закрытия, потому что это гораздо проще.

Таким образом, если мы идем вперед и написать, что в регулярной функции, я бы назвал это "compareTwo", и это занимает два параметра, они оба целые числа, я буду называть их первый и второй, и возвращает Буль. Я сделал опечатку там, я сказал функцию вместо FUNC. Давайте избавимся от этого. и я использую сокращенную метод здесь, что это просто будет непосредственно возвращать логическое сравнение между двумя, так что если первый меньше, чем второй, мы вернем правда. Если что-нибудь, кроме того, мы собираемся вернуться ложным. Таким образом, очень просто кусок кода здесь, но это должны делать свое дело.

Мы будем преобразовать это из функции в оболочке всего за секунду. Теперь ниже этого, мы собираемся, чтобы иметь вызов встроенного в отсортированном функции, и это только доступно в любой точке Свифт. отсортированный вернет отсортированный версию вашей коллекции, отсортированного версии массива или словаря, так что я буду создавать новую постоянную для получения результатов в, и мы перезвоним отсортированы. Первая часть информации, чтобы пройти в наш несортированный массив, который я создал на линии пять. Тогда запятая и затем мы должны закрыть.

Итак, я собираюсь превратить эту функцию в оболочке. Первое, что я собираюсь сделать, это просто, на самом деле, это прокомментировать, потому что я не хочу Свифт жаловаться на него со всем, что я делаю здесь. Итак, как мы это делаем? Ну, сначала я избавиться от FUNC и имя функции, не нужно. Затем, фигурные скобки нужно двигаться право начале, потому что закрытие открывает в фигурные скобки. Таким образом, мы имеем открывающую фигурную скобку, у нас есть информация от параметра и информацию возвращаемого типа. Тогда у нас есть тело закрытия.Только в прошлом, что мне нужно сделать, это отдельный, что с словом здесь.

И это должно работать, как наш закрытия. И мы просто раскомментировать, что мы, конечно, не нужно его сам по себе. Мне нужно, чтобы сократить его, вставьте его после этого и убедитесь, что для завершения закрытия скобки для отсортированного вызова. И, похоже, это нужно делать какой-то из 37 сравнений в его сравнивает, это, вероятно, делать какие-то пузырьковой сортировки, это действительно не имеет значения, я не волнует, что много. То, что я заинтересованы в том, результатом, так что я собираюсь ввести имя массиве сюда, а потом просто перейти по ней и найти значок Быстрый просмотр, и мы видим, что да, мы начали с случайным несортированный массива и теперь это один, два, три, четыре, 23, 98, она выглядит идеально, она выглядит в нужном количестве и с правой структуры.

И в самом деле, это всего лишь очень небольшой пример в пользу знакомство с замыканий. Затем, когда вы понимаете, как их использовать, вы можете подключиться к огромным количеством функциональных возможностей всей рамках Apple. Не только с сортировкой, но с сетевого кода и параллелизма и анимации, есть много частей функциональности, которые были определены для вас обеспечить только немного дополнительной логики и вы, что, предоставляя замыкания. Все они ожидают знакомство с этой идеей, и ваша жизнь намного проще, когда у вас есть, что.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]