С Xcode 11 Apple держит Swift на ходу. Давайте посмотрим на новые ключевые функции

20 сентября Apple выпустила совершенно новый Xcode 11, обеспечивающий существенную поддержку новой iOS 13. Как всегда, были представлены новые iPhone, и Apple выпустила новую версию своей IDE, содержащую поддержку новой версии своего языка разработки: Swift 5.1.

Даже если это не основной выпуск, Swift 5.1 объединяет новые языковые функции и улучшенную стабильность модуля.

Новое «Я» (да, заглавная буква «S»)

При использовании статического подхода к методам ООП в Swift принято ссылаться на имя класса. В предыдущих версиях Swift можно было ссылаться на имя класса по явной ссылке или с помощью self.dynamicType при использовании экземпляра объекта.

Во время создания подклассов self.dynamicType становится более интересным для ссылки на тип, который предназначен в этой части кода. Новый Self в основном заменяет старый self.dynamicType, который все еще поддерживается и отлично работает.

Вот почему теперь вы можете просто использовать ключевое слово Self для ссылки на имя класса:

class MediumAuthor {
 static func sayHello() {
    print(“Hello guys!”)
 }
 func newMethod() {
  Self.sayHello()
  // equals to MediumAuthor.sayHello()
 }
}

Синтезированные значения по умолчанию в поэлементных инициализаторах

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

В Swift 5.1 эта реализация автоматическая, разработчики старой школы сказали бы, что свойства автоматически синтезируют свои значения по умолчанию. Итак, вместо реализации метода init вы просто присваиваете им настраиваемое значение, например:

struct MediumAuthor {
  let name : String
  var articles = 0
}
let theAuthor = Author(name: "Ivano Di Gese")
// there's no need of implementing init() setting the articles default value

Непрозрачные возвращаемые типы

Эта функция позволит разработчикам лучше понять наследование и создание подклассов с помощью упрощенного механизма обработки типов.

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

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

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

Вот почему теперь можно использовать следующий синтаксис:

func getAnimal() -> some Animal {
   return Dog() // or Cat(), or Elephant() or whatever
}

Вы можете задаться вопросом, почему мы не можем использовать только обозначение -> Animal. Это зависит от того, как вы используете Self и реализуете методы в классе, потому что в некоторых случаях это могло вызвать ошибку компиляции.

Например, при сравнении объекта, если вы используете ключевое слово some, Swift будет правильно обрабатывать тип таким, какой он есть в данный момент, а не выдавать ошибку.

Статические индексы и индексы классов для динамического доступа

Поскольку индексирование широко используется разработчиками Swift, Apple улучшила его реализацию с помощью упрощенного синтаксиса для доступа к членам класса, свойствам перечислений и многому другому.

В Swift 5 вы можете создавать методы get() и set() для доступа к определенным значениям внутри списка свойств объекта, и вы можете использовать статические атрибуты, чтобы сделать методы связанными с классами, а не с экземплярами.

В Swift 5.1 вы можете лучше создать subscript() метод для индексирования объекта и возврата желаемого значения:

public class MyJson {
 private static var json = [String: String]()
 
 public static subscript(keyName: String) -> String? {
 
   get {
     return json[keyName]
   }
   set {
     json[keyName] = newValue
   }
 }
}
MyJson[“author”] = “Ivano”
print(MyJson[“author”] ?? “Unknown author”)

Неявный возврат из функций с одним выражением

В Swift 5 по-прежнему разрешалось опускать ключевое слово return в любое время, когда закрытие не имело ничего другого, кроме как вернуть значение.

Это похоже на поведение JavaScript, когда вы используете стрелочные функции и пропускаете ключевые слова возврата, как правило, к map(), reduce() и подобным реализациям.

Вот почему в Swift 5 вы можете легко присвоить значение переменной let, просто используя функцию map() или reduce() в правой части присвоения без специального ключевого слова return.

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

func multiply() -> Int {
 reduce(0) { $1.isMultiple(of: 2) ? $0 + $1 : $0 }
}
func decrement(myNumber : Int) -> Int {
 myNumber - 1 // no need of "return"!
}

Разница в заказанной коллекции

Наконец-то стало возможным получить разницу между упорядоченными коллекциями с помощью упрощенных методов.

Коллекции и массивы часто используются разработчиками из-за их частого использования в качестве источников данных для объектов UITableViews и UICollectionViews, поэтому эта новая функция очень ценится.

Новый метод difference(from:) вычисляет различия, на которые можно ссылаться для двух целевых коллекций, даже давая вам возможность циклически просматривать их и оценивать их.

let myFirst = [10, 20, 30]
let mySecond = [10, 40, 50]
let differences = mySecond.difference(from: myFirst)
// differences will contain references to evaluate removing and inserting actions to have arrays containing same values

Выводы и другие улучшения

Swift 5.1 увеличивает стабильность Swift 5, сокращая время компиляции модулей.

Стабильность модуля также использует текстовый файл интерфейса модуля, который описывает API двоичной структуры, что позволяет компилировать ее с кодом, используя разные версии компилятора.

SwiftSyntax также был обновлен и будет работать быстрее при посещении синтаксического дерева и при использовании внутренних данных.

В этой краткой статье я рассказал об обновлении Swift, но не об обновлении Xcode 11, которое встроено в то же обновление macOS.

Xcode 11 имеет несколько улучшений, включая поддержку SwiftUI и некоторые новые функции внешнего вида. Обновление Xcode и переход на новое языковое обновление Swift, несомненно, улучшат ваши профессиональные навыки разработчика iOS.