Roblox GuidebookБаза знаний
Русский ⌄

Разработка / ROBLOX

Функции Luau: параметры, return и проверка результата

Научитесь получать результат функции, отличать return от print и проверять входные данные. Разберём учебный счётчик оставшихся точек маршрута с готовыми примерами и проверками пограничных случаев.

Обновлено:

Сначала определите вопрос, на который отвечает функция #

Представьте учебную прогулку по десяти точкам. Мы знаем общее количество точек и сколько уже посещено. Нужно вычислить оставшееся количество. Здесь функция отвечает только на арифметический вопрос: сколько получится, если из total вычесть visited? Она не перемещает персонажа, не читает сохранения и не подтверждает посещение точек в настоящей игре.

Запишите смысл входных значений заранее: total — количество точек всего, visited — количество посещённых точек. Оба значения считаем целыми неотрицательными числами, причём посещённых не может быть больше общего количества. Это условие учебного примера, а не универсальное правило всех игровых маршрутов. Такая запись помогает обсуждать ошибку конкретно: неверен вход, вычисление или ожидание?

Определите функцию и вызовите её #

Первый пример создаёт local function remainingStops(total, visited). Между объявлением и end находится тело функции; return передаёт вычисленную разность вызывающему коду. Само объявление ещё не выполняет этот расчёт. Выполнение начинается при вызове remainingStops(10, 3), где значения в круглых скобках становятся аргументами.

Два вызова сохраняют результаты в разные переменные. Для десяти точек и трёх посещённых ожидаем 7; для тех же десяти и шести посещённых — 4. После этого print показывает сохранённые значения. Выполните весь блок в отдельном учебном Script и сравните две строки Output с ожиданием. Примеры также проверены отдельным интерпретатором Luau; это проверка языка и вычислений, а не тест игрового маршрута в Studio.

Вызов и возвращённый результатОткрыть изображение крупнее ↗
Оригинальная схема вычисления. Она не подтверждает игровой прогресс.
local function remainingStops(total, visited)
    return total - visited
end
local firstRemaining = remainingStops(10, 3)
local secondRemaining = remainingStops(10, 6)
print(firstRemaining)
print(secondRemaining)

Отличайте параметры от переданных значений #

total и visited — имена параметров внутри функции. Числа 10 и 3 — аргументы конкретного вызова. При следующем вызове те же параметры получают другие значения. Название внешней переменной не обязано совпадать с именем параметра: можно передать значение из routeLength, если оно соответствует оговорённому смыслу total.

Порядок имеет значение: remainingStops(10, 3) и remainingStops(3, 10) описывают разные входы. Первоначальная простая функция не проверяет смысл аргументов и во втором случае вычислит отрицательное число. Не пытайтесь исправить ошибку переименованием вывода. Сначала сравните порядок и значения аргументов с договорённостью о входных данных, затем добавьте проверку допустимости.

Посмотрите, почему print не заменяет return #

Во втором примере showRemaining печатает разность внутри своего тела. При вызове с 10 и 3 в Output действительно появляется 7. Но функция ничего не возвращает явно. Переменная result, которой присваивается результат вызова, получает nil. Поэтому последующий print(result) показывает nil, а не повторяет семёрку.

Это важная диагностика: правильная строка в Output ещё не доказывает, что вызывающий код получил нужное значение. Если интерфейс должен использовать число позже, вычисляющая функция должна вернуть его. Для учебной проверки оставьте оба print и наблюдайте две строки: сначала число из тела функции, потом nil из вызывающего кода. Не исправляйте это подстановкой постоянной семёрки: следующий вызов должен работать с другими входами.

Вывод и результат — разные вещиОткрыть изображение крупнее ↗
Оригинальная схема: сообщение в Output и возвращаемое значение различаются.
local function showRemaining(total, visited)
    print(total - visited)
end
local result = showRemaining(10, 3)
print(result)

Сохраните результат там, где он нужен #

В первом примере firstRemaining и secondRemaining содержат возвращённые числа. Вызывающий код может сравнить их с ожиданием, передать дальше или вывести. Функция вычисления и способ представления результата оказываются отдельными шагами. Для объяснения достаточно сохранить результат в локальную переменную и проверить его; создавать интерфейс ради освоения return не требуется.

Следите за строками после return внутри той же ветки: возврат завершает выполнение этой ветки функции. Не размещайте там дальнейший расчёт, который должен изменить возвращённое значение. Если нужно несколько значений, Luau позволяет вернуть их через запятую. Ниже используем пару «результат, признак допустимости», чтобы отсутствие результата не путалось с успешным окончанием маршрута.

Проверьте входы перед вычислением #

Третий пример checkedRemaining сначала проверяет типы. При пропущенном visited параметр получает nil, и функция возвращает nil, false до арифметики. Строка "10" также отклоняется: этот пример принимает числа и не занимается разбором текстового ввода. Затем исключаются NaN и положительная бесконечность; отрицательные значения и отрицательная бесконечность не проходят проверку на отрицательность.

Проверка остатка от деления на 1 отсеивает дробные количества. Последнее условие отклоняет visited больше total. Только после этих условий функция возвращает total - visited, true. Такой порядок позволяет читать правило по шагам. Это защита учебного расчёта от неподходящих входов; она не доказывает, что присланное клиентом число соответствует реальному прогрессу игрока.

local function checkedRemaining(total, visited)
    if type(total) ~= "number" or type(visited) ~= "number" then
        return nil, false
    end
    if total ~= total or visited ~= visited then
        return nil, false
    end
    if total == math.huge or visited == math.huge then
        return nil, false
    end
    if total < 0 or visited < 0 or total % 1 ~= 0 or visited % 1 ~= 0 then
        return nil, false
    end
    if visited > total then
        return nil, false
    end
    return total - visited, true
end
print(checkedRemaining(10, 3))
print(checkedRemaining(10))
print(checkedRemaining(10, 12))

Разберите пропущенный и лишний прогресс #

В блоке три вызова. checkedRemaining(10, 3) выводит 7 и true. checkedRemaining(10) выводит nil и false, поскольку второй аргумент отсутствует. checkedRemaining(10, 12) тоже выводит nil и false: двенадцать посещённых точек не соответствуют маршруту из десяти по выбранному правилу.

Когда сохраняете пару, используйте local value, valid = checkedRemaining(total, visited). Прежде чем показывать число пользователю, проверьте valid == true. Для false подготовьте понятное сообщение о некорректных данных. Не превращайте nil в ноль автоматически: это скроет ошибку и будет выглядеть как успешно завершённый маршрут. Исправлять вход нужно там, где он сформирован.

Считайте ноль допустимым результатом #

Если посещены все десять точек, checkedRemaining(10, 10) возвращает 0, true. Это успешное вычисление. Для пустого учебного маршрута checkedRemaining(0, 0) тоже возвращает 0, true. Отсутствие результата обозначаем nil, false; оно имеет другой смысл, чем число ноль.

В Luau ноль является истинным значением в условии, но явная проверка valid == true лучше объясняет договорённость этой функции. Не используйте сравнение value > 0 как единственный признак успешного вычисления: оно исключит правильный нулевой результат. Проверку завершения маршрута можно обсуждать отдельно после проверки допустимости, если игровая система действительно использует такую модель.

Проверяйте границы, а не только удачный вызов #

Составьте таблицу: 10 и 3 дают 7; 10 и 0 дают 10; 10 и 10 дают 0; 0 и 0 дают 0. Для каждого случая ожидаем true. Отдельно запишите неверные входы: отсутствующий второй аргумент, строка вместо числа, отрицательное число, дробь и посещение сверх общего количества. Здесь ожидаем nil и false.

В проверочном файле эти случаи выполнены с assert, дополнительно проверены NaN и бесконечность. Сохраните ожидаемые результаты до запуска, затем сравните реальные. Если результат отличается, укажите конкретный вход и полученную пару значений. Один удачный вызов не проверяет все правила, а успешная арифметика не проверяет сохранение прогресса, доверие к клиенту или выдачу награды.

Вход total / visitedОжидаемый результат
10 / 37, true
10 / 100, true
0 / 00, true
10 / без второго аргументаnil, false

Передайте функцию вместе с её договорённостью #

Для следующего разработчика сохраните имя функции, смысл и порядок параметров, допустимые входы, пару возвращаемых значений и таблицу проверок. Укажите, что это исходный учебный пример на чистом Luau. Если позже подключается настоящий маршрут, отдельно определите, откуда сервер получает подтверждённые total и visited и как реагирует на отсутствующие данные.

Не подписывайте материал как готовую систему прохождения или сохранений: в нём нет объектов Roblox, событий, сетевого обмена и постоянного хранилища. Полезный итог упражнения — умение отделить вывод в Output от результата, доступного вызывающему коду, и проверить это на нескольких понятных входах. После этого можно расширять задачу, сохраняя проверенную договорённость функции.

ПолеЧто сохранить
ПараметрыОбщее и посещённое количество
ПравилаЦелые конечные неотрицательные числа
РезультатЧисло и отдельный флаг valid
ПроверкиОбычные и граничные входы

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

Roblox Creator Hub — Functions