Вариативные функции (...)
Часть раздела Логика и управление потоком путешествия по Lua на Coddy. Урок 11 из 54.
Иногда нужна функция, которая может работать с любым количеством аргументов. Возможно, вы хотите вычислить сумму двух чисел, трёх или десяти, не создавая отдельные функции для каждого случая. В Lua для этого есть специальный синтаксис: три точки ...
Если поместить ... в список параметров функции, она станет функцией с переменным числом аргументов, принимающей любое количество аргументов:
function sum(...)
-- Тело функции
endВнутри функции ты снова можешь получить доступ к этим аргументам, используя .... Чтобы с ними было удобнее работать, можно упаковать их в таблицу с помощью фигурных скобок:
function sum(...)
local args = {...}
local total = 0
for i = 1, #args do
total = total + args[i]
end
return total
end
print(sum(5, 10, 15)) -- Вывод: 30
print(sum(1, 2, 3, 4, 5)) -- Вывод: 15Выражение {...} создаёт таблицу в виде списка, содержащую все аргументы, переданные функции. Затем по этой таблице можно пройтись, как и по любой другой, используя оператор длины # или ipairs().
Это работает, пока ни один аргумент не равен nil. Значение nil оставляет в таблице пропуск, а оператор # ненадёжен для таблицы с пропусками. select("#", ...) всегда возвращает количество аргументов, включая аргументы со значением nil:
function countArgs(...)
return select("#", ...)
end
print(countArgs(10, 20, 30)) -- Вывод: 3
print(countArgs(10, nil, 30, nil)) -- Вывод: 4Задание
ЛегкоНапишите функцию calculateAverage, которая принимает любое количество числовых аргументов и возвращает их среднее значение.
Используйте вариативный синтаксис ..., чтобы принимать произвольное количество аргументов, упаковывать их в таблицу, вычислять их сумму и делить её на количество аргументов.
Примечание: Стартовый код (помеченный как "Don't touch this code") считывает числа из ввода, преобразует каждое из текста в число с помощью tonumber() и сохраняет их в таблице с именем numbers. В конце он вызывает вашу функцию, используя unpack(numbers), которая передаёт значения таблицы как отдельные аргументы, поэтому ваша функция получает их в виде .... Вам не нужно изменять этот код или подробно разбираться в нём; просто сосредоточьтесь на написании calculateAverage.
Логика:
- Упакуйте все аргументы в таблицу с помощью
{...} - Пройдите по таблице, чтобы вычислить сумму всех чисел
- Разделите сумму на количество аргументов, чтобы получить среднее значение
- Верните среднее значение в виде числа
Параметры:
...(числа): Произвольное количество числовых аргументов
Возвращает: Среднее значение всех переданных чисел (число)
Попробуйте сами
-- Не трогайте этот код --
local numbers = {}
while true do
local input = io.read()
if input == nil or input == "" then
break
end
local num = tonumber(input)
if num then
table.insert(numbers, num)
end
end
-------------------------
function calculateAverage(...)
-- Напишите код здесь
end
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и управление потоком
1Продвинутая итерация таблиц
Итерация с помощью pairs()Итерация с помощью ipairs()pairs() против ipairs()Повторение — Лист персонажа2Дополнительные функции библиотеки table
table.concat()Создание таблиц и unpack()table.sort()Пользовательская сортировка с помощью функцийИтоги — Таблица рекордов3Продвинутые концепции функций
Возврат нескольких значенийВариативные функции (...)Функции как объекты первого классаАнонимные функцииЧто такое замыкание?Итоги — простой обработчик событийПотренируйтесь самостоятельно: Онлайн-компилятор Lua