Безопасность Nil в строгом режиме
Часть раздела Введение в Luau путешествия по Lua на Coddy — урок 71 из 73.
Самый частый сбой в Lua — это "attempt to index nil" — код, который предполагал, что значение существует, хотя его не было. Ответ Luau на это — дисциплина nil: в режиме --!strict обычный string никогда не может быть nil. Если nil действительно возможен, тип должен явно указывать на это с помощью ?:
--!строгий
local nickname: string? = nil -- ок: string ИЛИ nil
local username: string = nil -- ✗ ошибка типа в строгом режимеЭта дисциплина работает в обе стороны: если задан string?, строгий режим не позволит вам использовать его как строку, пока вы не исключите nil. Стандартный инструмент — обычное сравнение, которое сужает тип так же, как проверка через typeof:
local function shout(name: string?): string
if name ~= nil then
return string.upper(name) -- здесь name — это string
end
return "NOBODY"
endЕсли nil указывает на ошибку, а не на допустимый случай, используйте assert: после assert(x ~= nil) анализатор типов считает x не равным nil до конца области видимости, а во время выполнения assert приводит к сбою сразу же, в месте ложного предположения, а не где-то далеко в коде.
Результат: анализатор типов заставляет обработать каждое значение, которое «может отсутствовать», прямо во время редактирования, и ошибка во время выполнения просто никогда не возникает.
Задание
ЛегкоОбработайте поля профиля пользователя, которые могут отсутствовать. Начните ваш файл с --!strict.
getDisplayName(fullName: string?): string— возвращаетfullName, если значение не равноnil, в противном случаеAnonymous User.formatEmail(email: string?): string— возвращает email в нижнем регистре (string.lower), если значение не равноnil, в противном случаеNo email provided.getUserInfo(name: string?, email: string?): string— использует обе функции и возвращаетName: [processed name], Email: [processed email].
Затем выведите на экран, каждый с новой строки:
getDisplayName("John Smith")getDisplayName(nil)formatEmail("ALICE@EXAMPLE.COM")formatEmail(nil)getUserInfo("Bob Johnson", "bob@test.com")getUserInfo(nil, nil)getUserInfo("Sarah Wilson", nil)
Попробуйте сами
--!strict
-- Напишите код здесь
-- 1) getDisplayName(fullName: string?): string — nil-check, fallback "Anonymous User"
-- 2) formatEmail(email: string?): string — string.lower or "No email provided"
-- 3) getUserInfo(name: string?, email: string?): string — объединить оба
-- 4) выведите семь тестовых вызовов из задания
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Введение в Luau
1Начало работы с Luau
Что такое Luau?Почему именно Luau?Ваш первый код на LuauПроверка типов и режимы ошибокИтоги: Введение в Luau4Работа с функциями
Типизация параметров и возвращаемых значенийТипизация анонимных функцийФункции, ничего не возвращающиеНеобязательные параметрыЗначения параметров по умолчаниюФункции с переменным числом аргументовОпределение типов функцийИтоги: типизированные функции2Базовые типы
Основные типы: num, str, boolТип 'any': лазейка в типизацииТип 'unknown'Nil и опциональные типыВывод типов на практикеЯвные аннотации типовИтоги: практика по базовым типам5Псевдонимы, объединения и пересечения
Псевдонимы типов для примитивовТипы объединения (Union)Работа с типами объединенияЛитеральные типыТипы пересечения (Intersection)Комбинирование псевдонимов типовИтоги: Сложные комбинации типов8Перечисления в стиле Luau
Паттерн перечислений (Enum) в LuauЧисловые перечисления с помощью таблицСтроковые перечисления как объединенияИспользование перечислений на основе литеральных объединенийЗамораживание константных таблицИтоги: Перечисления в стиле Luau11Продвинутые темы
Утверждение типов (Type Assertions)Сужение типов с помощью typeof (Type Guards)Тип neverБезопасность Nil в строгом режимеИндексные сигнатурыИтоги: точная настройка типов3Типизированные таблицы: Массивы и Map-словари
Типизированные массивыДобавление и чтение элементовЧто такое тип Map?Объявление и доступ к Map-словарямИтерация по таблицамТаблицы смешанной формыМногомерные типизированные массивыtable.unpack и VarargsИтоги: Массивы и Map-словари