Лекция 5 | Stanford CS193p 2023

YOUTUBE · 28.11.2025 07:28

Ключевые темы и таймкоды

Введение и типы перечислений

0:01
  • Демонстрация продолжит предыдущую тему.
  • Обсуждение типа перечисления и необязательного типа.
  • Завершение с логикой игры для приложения.

Разница между назначенным объектом наблюдения и назначенным объектом состояния

0:30
  • Продолжительность жизни переменной зависит от типа назначенного объекта.
  • Назначаемое состояние внутри представления существует только во время его отображения.
  • Назначаемое состояние в приложении существует все время.

Наблюдаемые объекты и их использование

1:46
  • Наблюдаемые объекты связаны с изменениями, а не с продолжительностью жизни.
  • Наблюдаемые объекты могут быть переданы между представлениями.
  • Создание объектов на лету для предварительных просмотров.

Введение в анимацию

3:56
  • Важность анимации в мобильных приложениях.
  • Демонстрация анимации для карточек.
  • Использование модификатора вида для анимации.

Проблемы с анимацией и протоколы

5:21
  • Ошибка при анимации карточек.
  • Объяснение необходимости соответствия протоколам для анимации.
  • Реализация функции equals для соответствия протоколу equatable.

Реализация функции equals

8:32
  • Создание статической функции equals для карт.
  • Проверка равенства карт по их внешнему виду и содержимому.
  • Проблема с несоответствием содержимого карт протоколу equatable.

Решение проблемы с содержанием карточек

10:40
  • Обсуждение необходимости одинакового содержимого карточек.
  • Использование "равных равному" в Swift для автоматического сравнения параметров.
  • Удаление ненужных сравнений для упрощения кода.

Анимация карточек

11:41
  • Проверка работы анимации после удаления ошибок.
  • Проблема с анимацией: карточки исчезают и появляются, а не двигаются по экрану.
  • Введение предикатов для индексации карточек.

Идентификация карточек

12:41
  • Проблема с индексацией карточек и необходимость их идентификации.
  • Использование идентификатора для каждой карточки.
  • Введение протокола "идентифицируемый" для уникальной идентификации карточек.

Создание идентификатора

16:09
  • Создание уникального идентификатора для каждой карточки.
  • Использование строки для идентификатора.
  • Применение интерполяции строк для создания идентификатора на основе индекса.

Проверка работы анимации

20:24
  • Проверка работы анимации после добавления идентификатора.
  • Анимация карточек при перетасовке.
  • Демонстрация мощи анимации и её важности для пользовательского интерфейса.

Пользовательское преобразование строк отладки

21:54
  • Swift позволяет преобразовывать любой тип текста в строку.
  • Для компактного вывода используется протокол пользовательского преобразования строк отладки.
  • Вводится строка с именем "debug description" для описания объекта.

Переворачивание карточек

23:48
  • Переворачивание карточек осуществляется через жест касания.
  • Используется намерение для выбора карточки.
  • Переворачивание карточки требует изменения индекса в массиве.

Различие между типами значений и ссылочными типами

25:13
  • Ошибка при попытке изменить карточку через "переключи".
  • Типы значений передаются по значению, а не по ссылке.
  • Для изменения карточки нужно использовать индекс в массиве.

Определение индекса карточки

27:05
  • Создается функция "карточный указатель" для определения индекса карточки.
  • Функция возвращает значение int, указывающее на индекс карточки.
  • Используется цикл for для нахождения нужной карточки по идентификатору.

Исправление ошибок и тестирование

29:02
  • Функция возвращает ноль, если карточка не найдена.
  • Используется инструмент "исправь меня" для исправления ошибок.
  • Тестирование показывает, что карточки переворачиваются при нажатии.

Завершение и подготовка к игре

30:46
  • Почти все готово для игры.
  • Использование необязательного типа в реализации модели.
  • Переход к следующему этапу для игры.

Введение в перечисления

31:07
  • Перечисления используются для типов данных с дискретными значениями.
  • Перечисления похожи на структуры и классы, но без сохраненных переменных.
  • Пример: пункты меню быстрого питания могут быть только гамбургер, картофель фри, напиток или печенье.

Типы значений и связанные данные

32:05
  • Перечисления являются типами значений и передаются по значению.
  • Можно связывать данные с каждым случаем перечисления.
  • Пример: количество котлет в гамбургере или размер картофеля фри.

Установка значений перечисления

33:02
  • Переменные типа перечисления могут быть установлены с помощью значений.
  • Swift может определить одну сторону равенства, но не обе.
  • Пример: пункт меню "гамбургер" или "печенье".

Использование switch для перечислений

34:14
  • Switch в Swift позволяет проверять каждый случай перечисления.
  • Пример: проверка пункта меню "гамбургер" с двумя котлетами.
  • Важно охватить все случаи перечисления или использовать default.

Связанные данные и функции

36:34
  • В switch можно извлекать связанные данные с помощью let.
  • Перечисления могут иметь функции и методы, но без сохраненных переменных.
  • Пример: функция для специального заказа в меню.

Перебор случаев перечисления

39:06
  • Перечисления должны соответствовать протоколу case iterable для перебора всех случаев.
  • Пример: использование статической переменной all cases для перебора всех случаев перечисления.

Необязательные типы

39:38
  • Необязательные типы используются для значений, которые могут быть неопределенными.
  • Пример: необязательный параметр типа "не важно".
  • Синтаксический сахар позволяет объявлять необязательные параметры с вопросительным знаком.

Необязательные строки и перечисления

41:43
  • Необязательные строки обозначаются вопросительным знаком после типа.
  • Необязательные строки могут быть равны нулю или содержать данные.
  • Присвоение значений необязательным строкам аналогично присваиванию значений связанным данным.

Принудительное разворачивание необязательных параметров

42:31
  • Принудительное разворачивание используется для получения значения необязательного параметра.
  • Принудительное разворачивание может привести к сбою программы, если параметр равен нулю.
  • Принудительное разворачивание полезно для отладки и выявления ошибок.

Использование if-let для обработки необязательных параметров

44:08
  • if-let позволяет безопасно использовать необязательные параметры.
  • Если параметр равен нулю, код не выполняется.
  • Пример использования if-let для обработки необязательных значений.

Пример использования необязательных параметров в коде

45:24
  • Необязательные параметры могут иметь значение по умолчанию.
  • Пример использования необязательной строки и значения по умолчанию.
  • Необязательные параметры помогают избежать ошибок и обеспечивают безопасность кода.

Обработка ошибок и использование необязательных параметров

46:06
  • Необязательные параметры позволяют возвращать значение null, если значение не найдено.
  • Пример использования необязательного параметра для возврата null.
  • Обработка ошибок с помощью if-let для предотвращения аварийных завершений работы.

Использование массивов и необязательных параметров

48:10
  • Массивы могут содержать необязательные значения.
  • Пример использования массива для проверки наличия карты.
  • Использование if-let для безопасного доступа к элементам массива.

Обработка ошибок и использование необязательных параметров в игровой логике

50:50
  • Необязательные параметры позволяют обрабатывать ошибки и возвращать null.
  • Пример использования необязательного значения для проверки наличия карты.
  • Обработка ошибок и использование if-let для безопасного доступа к элементам массива.

Обработка карт

51:39
  • Если карта лежит рубашкой вверх, игрок игнорирует её.
  • Если две карты лежат рубашкой вверх и не совпадают, игрок переворачивает их обратно.
  • Если карта нажата, игрок переворачивает её лицевой стороной вверх.

Структура данных

52:48
  • Важно определить структуру данных для алгоритма.
  • В карточной игре используется структура данных для отслеживания одной открытой карты.
  • Если одна карта лежит лицевой стороной вверх, игрок пытается сопоставить её.

Инициализация данных

54:16
  • Ошибка при инициализации данных решается использованием optional int.
  • В начале игры все карты открыты, поэтому используется значение null.

Реализация алгоритма

55:09
  • Проверка совпадения карт с индексом потенциального совпадения.
  • Если карты совпадают, они помечаются как совпадающие.
  • Если нет совпадений, все карты переворачиваются лицевой стороной вниз.

Проверка работы алгоритма

57:56
  • Проверка работы алгоритма на практике.
  • Логика игры работает корректно, но требует улучшений.

Усовершенствование алгоритма

59:58
  • Использование вычисляемого свойства для определения индекса одной открытой карты.
  • Создание массива индексов открытых карт для упрощения работы.
  • Игрок должен проверять наличие одной открытой карты перед каждым действием.

Массив индексов открытых карт

1:02:02
  • Массив всех индексов открытых карт.
  • Если есть только одна открытая карта, возвращается её индекс.
  • Если нет открытых карт, возвращается nil.

Установка индекса открытой карты

1:02:56
  • Если индекс открытой карты равен новому значению, все остальные карты переворачиваются.
  • Использование вычисляемого свойства для установки индекса.
  • Код становится более жестким и минимальным.

Функциональное программирование

1:05:07
  • Использование функционального программирования для упрощения кода.
  • Фильтрация индексов карт, лежащих лицевой стороной вверх.
  • Использование функции для установки нового значения.

Расширение массива

1:07:33
  • Добавление функции only в массив для возврата единственного элемента.
  • Использование функции для фильтрации и возврата единственного элемента.
  • Упрощение кода и улучшение читаемости.

Домашнее задание

1:10:46
  • Домашнее задание номер два должно быть выполнено в понедельник.
  • Домашнее задание номер три - написать собственную карточную игру.
  • В понедельник будет обсуждаться создание фигур для игры.