Swift Notes
33 subscribers
22 photos
3 videos
1 file
23 links
Обучающие материалы и полезные заметки по языку программирования Swift. Изначально задумывался, как моя личная записная книжка в процессе обучения. Связаться со мной @clockber
Download Telegram
Реализация методов в перечислениях. #enumerations #mutating

В Swift перечисления(enumerations) являются действительно первоклассными типами и обладают несколькими расширенными возможностями. Одной из таких возможностей является возможность определять методы для case внутри перечисления.

Одним из таких вариантов использования является мутирующий метод в перечислении. Мутирующий метод - это метод, который изменяет значения своих же case при выполнении. Давайте рассмотрим пример с перечислением сезонов, чтобы вникнуть в концепцию.
Реализация вычисляемого свойства в перечислении. #enumerations #propetry

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

Рассмотрим перечисление Patty
Мы неявно присваиваем необработанные целочисленные значения каждому из случаев Patty. Затем мы реализуем дополнительное свойство вычисления пирожков pattyCountWithExtraPatty, которое возвращает целое значение, равное rawValue плюс 1.

Вычисляемое свойство может возвращать значение любого типа, и оно не обязательно должно совпадать с исходными значениями перечисления. Фактически, вам даже не нужно устанавливать исходные или связанные значения для случаев перечисления, чтобы реализовать вычисляемое свойство в перечислении.
#enumerations #property

//Eще один пример вычисляемого свойства в перечислениях(enumerations), создаем перечисление Vehicle —>

enum Vehicle {
case airplane
case boat
case truck(isFourWheelDrive: Bool)

//далее добавляем вычисляемое свойство description —> в нем перечисляем все case и заставляем выводить строку в соответствии с каждым случаем

var description: String {
switch self{
case .airplane:
return "This is an airplane"
case .boat:
return "This is a boat"
case let .truck(isFourWheelDrive):
return "This is a truck" + (isFourWheelDrive ? " with four wheel drive" : "")
}
}
}

// А в конце самое интересное, создаем константу myRide которую мы отнесем к Vehicle, добавим в ее свойства параметр, допустим true и сделаем ее принт.
И swift прекрасен😍

let myRide = Vehicle.truck(isFourWheelDrive: true)

print(myRide.description)

//Выведет: This is a truck with four wheel drive
Введение в Enumerations (Перечисления) #enumerations

🔹Обладая некоторыми формами информации, допустим мы знаем все возможные значения, которые могут существовать. Например, вы создаете транспортное приложение. Пользователи могут путешествовать на грузовике, самолете или лодке.

Мы могли бы просто использовать строку для хранения этой информации:

var myRide = "грузовик"

🔹Но такая запись не помешает нам назначить для MyRide значение, которое не является допустимым типом поездки:

myRide = "крылатые обезьяны"

Так можно легко запутаться! К счастью, Swift позволяет нам ограничить возможные значения, которыми может быть переменная.

🔹Перечисление(enumerations), часто сокращаемое до enum - это способ определить свою собственную группу связанных значений и работать с ними безопасным для типов способом. С помощью приведенного ниже перечисления мы всегда будем знать, какие транспортные средства действительны:

enum Vehicle {
case airplane
case boat
case truck
Что такое Перечисления? #enumerations

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

🔹Перечисления определяются с помощью ключевого слова enum и фигурных скобок:

enum MyDataType {
// перечесления живут тут
}

🔹Используется ключевое слово case для определения случаев в вашем перечислении:

enum DogBreed {
case corgi
case husky
case samoyed
case shibaInu
}

🔹запись может быть через запятую:

enum DogBreed {
case corgi, husky, samoyed, shibaInu
}

🔹инициализация переменных наделенных свойствами перечислений, будет выглядеть так:

var bella = DogBreed.samoyed
После того как изучены и отработаны базовые понятия по свифту, очень рекомендую курс Ангелы Ю, со скидкой брал его чуть ли не за 700 рублей. В нем разобрано достаточно хорошо взаимодействие со SwiftUI, получите в копилку много проектов (написанных вами приложений). О да, начинал я с ютубчика и потом брал курс на Скиллбоксе, который быстро решил сбросить, что бы не тратить время и деньги. Вообщем пинать вас к обучению в текущий момент времени вряд ли кто-то будет, даже за ваши деньги! Ищите мотивацию, я ищу ее у себя в канальчике :)

https://www.udemy.com/course/ios-13-app-development-bootcamp/
#array #set #dictionaries

Очень классная картинка, которая указывает на различия между массивами, словарями и множествами.
Опционал #optionals

🔹Когда мы работаем с данными, иногда мы обнаруживаем, что информация для переменной может отсутствовать. Давайте представим, что вы пишете программу, которая отображает первую букву фамилии пользователя.

let firstName = "Peter"
let middleName = "Hubert"
let lastName = "Penn"

🔹Фамилия пользователя в нашем примере “Penn”, поэтому наша программа должна напечатать “P”. Но как насчет пользователя из второго примера?

let firstName = "George"
let middleName = "Michael"
let lastName = ""

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

🔹Опциональные типы содержат либо значение, либо ноль. Необязательный тип определяется знаком вопроса:

var firstLetter: Character?

🔹Начальное значение опционала будет равно nil, пока вы сами не назначите значение:

var firstLetter: Character?
print(firstLetter) // выведет nil
firstLetter = “a”
print(firstLetter) // выведет Optional("a")

🔹nil может быть присвоено только опциональной переменной. Если вы попытаетесь присвоить nil обычной переменной, вы получите ошибку во время компиляции.

var firstLetter: Character = “a”
firstLetter = nil // ERROR: nil' cannot be assigned to type 'Character'
Принудительное раскрытие (разворачивание) опционала / Force Unwrapping Optionals #optionals

🔹Как только вы создадите опциональную переменную, вы захотите попробовать использовать значению внутри. Однако, если вы просто попытаетесь использовать опциональную переменную, вы получите ошибку во время компиляции:

var x = 5
var y: Int? = 2
let sum = x + y // ERROR: Value of optional type 'Int?' must be unwrapped to a value of type 'Int'

🔹Самый простой путь использования значения в опциональной переменной, это использование > ! < оператора, что называется "принудительное раскрытие", мы получаем следующее:

var x = 5
var y: Int? = 2
let sum = x + y!
print(sum) // вывод 7

🔹Но будьте осторожны, если переменная будет иметь параметр nil, программа развалиться:

var x = 5
var y: Int? = nil
let sum = a + b! // Fatal error: Unexpectedly found nil while unwrapping an Optional value
print(sum)

🔹Прежде чем использовать оператор ! , убедитесь что значение опциональной переменной не будет рано nil. В большинстве случаев, что будет правильнее, используется оператор if, наш код принимает следующий вид:

var a = 4
var b: Int? = nil
if b != nil {
let sum = a + b!
print(sum) Prints 7
}
Что такое optional и какие проблемы они решают? #optionals

🔹optional позволяет переменной любого типа представить ситуацию "отсутствие значения". В Objective-C «отсутствие значения» было доступно только в ссылочных типах с использованием специального значения nil. У типов-значений (value types), вроде int или float, такой возможности не было.
Swift расширил концепцию «отсутствия значения» на типы-значения. Переменная optional может содержать либо значение, либо nil, сигнализирующее об отсутствии значения.
Коротко основные отличия между structure и class. #structures #classes

🔹Классы поддерживают наследование, а структуры — нет.
Классы — ссылочный тип, структуры — тип-значение.
Что такое generics и для чего они нужны? #generics

🔹 В Swift вы можете использовать generics в классах, структурах и перечислениях.

🔹 Generics устраняют проблему дублирования кода. Если у вас есть метод, который принимает параметры одного типа, иногда приходится дублировать код, чтобы работать с параметрами другого типа.

🔹 Например, в этом коде вторая функция — это «клон» первой, за исключением того, что у неё параметры string, а не integer.

func areIntEqual(_ x: Int, _ y: Int) -> Bool {
return x == y
}

func areStringsEqual(_ x: String, _ y: String) -> Bool {
return x == y
}

areStringsEqual("ray", "ray") // true
areIntEqual(1, 1) // true

🔹 Применяя generics, вы совмещаете две функции в одной и одновременно обеспечиваете безопасность типов:

func areTheyEqual<T: Equatable>(_ x: T, _ y: T) -> Bool {
return x == y
}

areTheyEqual("ray", "ray")
areTheyEqual(1, 1)

🔹 Так как вы тестируете равенство, вы ограничиваете типы теми, которые отвечают протоколу Equatable. Этот код обеспечивает требуемый результат и препятствует передаче параметров неподходящего типа.
В некоторых случаях не получится избежать неявного разворачивания (implicitly unwrapped) optionals. Когда и почему? #optionals

🔹Наиболее частые причины для использования implicitly unwrapped optionals:

когда вы не можете инициализировать свойство, которое не nil в момент создания. Типичный пример — outlet у Interface Builder, который всегда инициализируется после его владельца. В этом особенном случае, если в Interface Builder всё правильно сконфигурировано — вам гарантировано, что outlet не-nil перед его использованием.
чтобы разрешить проблему цикла сильных ссылок, когда два экземпляра классов ссылаются друг на друга и требуется не-nil ссылка на другой экземпляр. В этом случае вы помечаете ссылку на одной стороне как unowned, а на другой стороне используете неявное разворачивание optional.
Внимание! Все способы разворачивания опционалов. #optionals
спойлер: всего их 7!

🔹1. Принудительное развёртывание (forced unwrapping) — небезопасно.

let a: String = x!

🔹2. Неявное развертывание при объявлении переменной — небезопасно.

var a = x!

🔹3. Optional binding — безопасно.

if let a = x {
print("x was successfully unwrapped and is = \(a)")
}

🔹4. Optional chaining — безопасно.

let a = x?.count

🔹5. Nil coalescing operator — безопасно.

let a = x ?? ""

🔹6. Оператор Guard — безопасно.

guard let a = x else {
return
}

🔹7. Optional pattern — безопасно.

if case let a? = x {
print(a)
}
В чём разница между nil и .none? #optionals

🔹 Нет никакой разницы, Optional.none (кратко .none) и nil эквивалентны.
Фактически, следующий оператор вернёт true:

nil == .none

🔹 Использование nil более общепринято и рекомендовано.
Жизненный цикл ViewController'a #ViewController

viewDidLoad()
viewWillAppear(_ animated: Bool)
viewDidAppear(_ animated: Bool)
viewWillDisappear(_ animated: Bool)
viewDidDisappear(_ animated: Bool)
Функции высшего порядка (Higher-Order functions) #functions

🔹 определяются как функции, принимающие другую функцию как аргумент или возвращающие функцию.

🔹 их много: map , filter , reduce , forEach , flatMap , compactMap ,sorted и т.д. Наиболее распространенными примерами функций высшего порядка являются функции map , filter и reduce.
Функции высшего порядка (Higher-Order functions) #functions
map, reduce, sorted, filter

🔹 Map: для преобразования содержимого массивов, map(_:)

//пример
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

func timesTen(_ x:Int) -> Int {
return x * 10
}

let result = numbers.map (timesTen)

print(numbers) //[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(result) //[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

🔹 Reduce: перебирает каждый элемент в коллекции и сводит их к одному значению, reduce (_:, _:)

//пример

let values = [3, 4, 5]
let sum = values.reduce(0, +)
print(sum)

//вывод: 12

🔹Sorted: сортировка массивов, основана на заданном вами замыкании, sorted(by:)

//пример (сортировка по алфавиту)

let avatarMovie = Movie(name: "Avatar")
let titanicMovie = Movie(name: "Titanic")
let piranhaMovie = Movie(name: "Piranha II: The Spawning")

let movies = [avatarMovie, titanicMovie, piranhaMovie]
let sortedMovies = movies.sorted(by: { $0 < $1 })

print(sortedMovies)

// вывод: [Avatar, Piranha II: The Spawning, Titanic]

🔹Filter: преобразует массив в соответствии с заданным условием, filter (_:)

//пример

let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let filted = numbers.filter{$0 % 2 == 0}
//[2, 4, 6, 8, 10]
30 days of Swift -  все заметки стараюсь делать с максимальной пользой, наткнулся на обалденый репозиторий в Git, там парнишка разместил 30 различных проектов на Swift начального уровня.

🔹Если в лом залезать в папочки и смотреть код, то там даже GIFки есть с отображением функционала :)) https://github.com/allenwong/30DaysofSwift
Цикл For в Swift
Цикл for базовый метод во всех языка, в swift часто называют for-in

🔹for-in для массива #collections #array
В примере итерация по массиву городов #array, в Swift массивы так же известны под таким понятием как коллекции #collections

let cities = ["Amsterdam", "New York", "San Francisco"]
for city in cities {
print(city)
}

вывод: // Amsterdam
// New York
// San Francisco

🔹for-in для словаря #dictionary
Пример итерации словаря. Выводим возраст

let ages = ["Antoine": 28, "Jaap": 2, "Jack": 72]
for (name, age) in ages {
print("\(name) is \(age) years old")
}

вывод: // Antoine is 28 years old
// Jaap is 2 years old
// Jack is 72 years old

🔹for-in для словаря последовательностей #range
В следующем примере берем #range и выполняем оператор печати 4 раза. Счет идет в обратном порядке, потому что мы его добавили .reversed, это также может использоваться в других циклах.

for index in (0...3).reversed() {
print("\(index)..")
}

/// 3..
/// 2..
/// 1..
/// 0..
Optionals (опционалы) #optionals — это удобный механизм обработки ситуаций, когда значение переменной может отсутствовать. Значение будет использовано, только если оно есть.

p.s: самое мое любимое,когда коротко и ясно :)