company_banner

Интервью — 10 вопросов про Swift. Часть 1

Автор оригинала: Animesh Mishra
  • Перевод
Салют, хабровчане! Майские закончились, и мы продолжаем запускать новые курсы. Эта статья приурочена к старту курса «iOS-разработчик». Обучение начнется 28 мая, а до тех пор у вас есть возможность побольше узнать о языке Swift и его особенностях. Это первая статья из трех, где в формате интервью рассматриваются достоинства и особенности языка Swift, на котором мы учим создавать приложения под iOS на наших курсах.




Что такое Swift и чем он хорош?


Swift — это универсальный и мультипарадигмальный язык программирования, разработанный корпорацией Apple для разработки решений под iOS, macOS, watchOS, tvOS и даже Linux.

  • Удобочитаемость — у языка Swift очень чистый и простой синтаксис, который легко как пишется, так и читается.
  • Легкая поддержка — на выходе получается гораздо меньше кода и уровней наследования, а весь проект превращается в один swift-файл.
  • Безопасная платформа — компилируйте и фиксите ошибки прямо во время написания кода.
  • Высокая скорость — невероятно быстрый и производительный компилятор LLVM преобразует написанный на Swift код в нативный, чтобы получить максимум отдачи от устройств. Сам синтаксис и стандартная библиотека также оптимизированы для быстрой работы.
  • Поддержка динамических библиотек.
  • Открытый исходный код.

В чем разница между классом и структурой?


В Swift есть четыре основных различия между классом и структурой. Классы имеют некоторые возможности, которых нет у структур:

  • Приведение типов — позволяет проверять и интерпретировать классы во время выполнения.
  • Подсчет ссылок — позволяет использовать более одной ссылки для каждого экземпляра класса.
  • Наследование — позволяет одному классу наследовать характеристики другого.
  • Деинициализаторы — позволяют каждому экземпляру класса освобождать все назначенные ему ресурсы.

Когда структуры передаются в коде, они всегда копируются без использования подсчета ссылок. Экземпляры структуры всегда передаются по значению, а экземпляры класса всегда по ссылке.

В каких случаях использовать класс, а в каких — структуру?


В качестве простой шпаргалки: структуры стоит использовать тогда, когда выполняется одно или несколько из следующих условий.

  • Задача структуры в том, чтобы инкапсулировать несколько относительно простых значений данных;
  • Можно ожидать, что инкапсулированные значения будут копироваться, а не ссылаться;
  • Хранящиеся в структуре свойства сами являются типами значений, которые также копируются, а не ссылаются;
  • Структура не должна наследовать свойства и поведение другого существующего типа.

В остальных случаях используйте классы: определите класс, создайте экземпляр для управления и передачи по ссылке.

Как передавать переменные в качестве ссылок?


Переменную можно передавать в качестве ссылки с помощью параметра inout. Inout означает, что изменение локальной переменной также изменит передаваемые параметры.

var value: String = “Apple”

func changeString(newValue:inout String) {
 newValue = “Samsung”
 print(newValue) // Output:Samsung
 print(value) // Output:Samsung
}

changeString(newValue:&value)


Что такое модуль?


  • Модуль — это отдельная единица в распределении кода;
  • Платформа или приложение, которое создается и распространяется как отдельная единица и может быть импортировано другим модулем;
  • Каждая цель сборки — пакет приложений или фреймворк в Xcode рассматривается как отдельный модуль.

Чем отличаются уровни доступа в Swift?


В Swift есть пять различных уровней доступа для сущностей в коде:

  • Открытый доступ — классы с открытым доступом могут являться подклассами или быть переопределены подклассами в модуле, где они определены, или в любом другом, который импортирует модуль, где они определены;
  • Публичный доступ — классы с публичным доступом могут являться подклассами или быть переопределены подклассами только в рамках модуля, где они определены;
  • Внутренний доступ — сущности могут использоваться в любом исходном файле из определяющего модуля, но не в исходном файле вне этого модуля;
  • Файл-частный доступ — использование сущностей ограничено собственным определяющим исходным файлом;
  • Частный доступ — использование сущностей ограничено вложенным объявлением и расширениями этого объявления, которые находятся в одном файле.

Открытый доступ является самым высоким и наименее ограниченным уровнем, а частный — самым низким и, соответственно, наиболее ограниченным. По умолчанию все сущности в коде имеют внутренний уровень доступа.

Что такое отложенная инициализация?


Отложенная инициализация — техника задержки создания объекта или выполнения другого процесса до тех пор, пока этот процесс не станет необходимым. Задержку можно использовать только с классами и структурами. Однако стоит понимать, что свойство lazy не является безопасным, потому что не инициализируется автоматически.

Вам всегда нужно объявлять свойство lazy как переменную с использованием var. Свойства констант всегда должны иметь значение до завершения инициализации, поэтому они не могут быть отложенными.

Что такое кортеж?


Кортеж — это группа из нуля или более значений, представленных как одно значение. Они обычно используются для возврата нескольких значений из функции вызова. В Swift два вида кортежей.

Именной кортеж

let nameAndAge = (name:”Midhun”, age:7)
Access the values like:
nameAndAge.name //Output: Midhun
nameAndAge.age //Output: 7


Безымянный кортеж
В этом типе кортежа мы не указываем имен для элементов.

let nameAndAge = (“Midhun”, 7)
Access the values like:
nameAndAge.0 //Output: Midhun
nameAndAge.1 //Output: 7


Что такое перечисления?


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

Что такое связанные значения?


Связанные значения очень похожи на переменные, связанные с одним из случаев перечисления.

enum Barcode {

case upc(Int, Int, Int, Int)

case qrCode(String)
}


Определяем тип перечисления Barcode, который может принимать либо значение upc со связанным значением типа (Int, Int, Int, Int), либо значение qrCode со связанными значением типа String.

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

Конец первой части.
Вторая часть.

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

Комментарии 12

    +2
    Честно говоря, сомнительная статья. Особенно глаз зацепился за следующее
    Безопасная платформа — компилируйте и фиксите ошибки прямо во время написания кода.

    Как связана безопасность и возможность фиксить ошибки во время выполнения? И, кстати, я не понимаю что автор имел в виду под фиксами во время выполнения.
    В Swift два вида кортежей.

    Кортеж это просто группировка значений и программист для собственного удобства может дать этим значениям имена, причем может дать их даже не всем, например, let a = (a: 1, 2, c:3) (другой вопрос что так лучше не делать), а может и наоборот к именованным переменным по номеру обращаться, так что никакого разделения на два типа по факту нет.
      0
      Про безопасность видимо имеется ввиду, что ошибки выявляются на этапе написания/компиляции, а не рантайма.
        0
        Ну так много кто выявляет ошибки на этапе компиляции/написания, даже для plain c ворнинги (которые легко превращаются в ошибку через -werror) посыпятся если попытаться, например, в указатель на double прокинуть указатель на int. Правда, я тут слазил в оригинал и там Safer т.е. платформа не «безопасная», а просто «безопаснее» [чем Obj-C] с чем сложно спорить и это косяк перевода
      0
      Уровни доступа зря перевели.
        0
        В каких случаях использовать класс, а в каких — структуру?

        Apple
        И еще на какой то сессии WWDC не согласились с популярным мнением, что struct для простых абстракций
          0
          Эх, были бы у меня такие вопросы на всех собеседованиях, давно бы в Facebook работал
            0
            Несмотря на то что оригинал статьи копипаст процентов на 99% из The Swift Programming Language но такие вопросы по Swift на собеседованиях реально спрашивают.
            0
            Прекрасно!
            Что бы пройти тестирование — надо зарегистрироваться, оставить свою почту, так сказать.
            А потом оказывается, что надо ещё и оставить свой номер телефона.
              0
              Не мог не зарегистрироваться ради разъяснений. inout не равно передаче по ссылке. Это заблуждение пошло людям с сишным бэкграундом. В си передача по ссылке изменила бы исходный объект. В Свифте inout не изменит объект до выхода из функции, а просто перезапишет при передаче управления. В официальном же учебнике про это в гонках памяти рассказано.
                +1
                Меня заинтересовал ваш комментарий и я решил проверить, накидал в плейграунде вот такой пример:
                import Foundation
                
                let sem1 = DispatchSemaphore(value: 0)
                let sem2 = DispatchSemaphore(value: 0)
                
                func quad(_ a: inout Int) {
                    print("Into function quad")
                    a = a * a
                    print("Internal a = \(a)")
                    sem1.signal()
                    sem2.wait()
                    print("Return from quad")
                }
                
                var a = 2
                print("Initial a = ", a)
                DispatchQueue.global().async {
                    quad(&a)
                }
                sem1.wait()
                print("After sem1 signal a = ", a)
                sem2.signal()
                DispatchQueue.global().asyncAfter(deadline: .now() + 1.0) {
                    print("Final a = ", a)
                }
                

                Вывод:
                Initial a =  2
                Into function quad
                Internal a = 4
                After sem1 signal a =  4
                Return from quad
                Final a =  4
                

                Как видите, строка «After sem1 signal a = 4» выводится до выхода из функции quad, но тем не менее там a уже равно 4. Либо я вас не правильно понял, либо же вы что-то не то написали
                  0
                  Поизучаю этот вопрос на досуге. Интересные дела)
                    0
                    Могу еще добавить что я пробовал и менять переменную снаружи пока функция висела на семафоре, тоже сработало в обе стороны

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

              Самое читаемое