Определение значений по умолчанию для аргументов функции

В Lua wiki я нашел способ определить значения по умолчанию для отсутствующих аргументов:

function myfunction(a,b,c)
    b = b or 7
    c = c or 5
    print (a,b,c)
end

Это единственный способ? Стиль PHP myfunction (a,b=7,c=5), похоже, не работает. Не то, чтобы способ Lua не работал, мне просто интересно, если это единственный способ сделать это.

Ответ 1

Если вам нужны именованные аргументы и значения по умолчанию, такие как PHP или Python, вы можете вызвать свою функцию с помощью конструктора таблицы:

myfunction{a,b=3,c=2}

(Это видно во многих местах Lua, таких как расширенные формы модулей протокола LuaSocket и конструкторы в IUPLua.)

Сама функция может иметь такую ​​подпись:

function myfunction(t)
    setmetatable(t,{__index={b=7, c=5}})
    local a, b, c =
      t[1] or t.a, 
      t[2] or t.b,
      t[3] or t.c
    -- function continues down here...
end

Любые значения, отсутствующие в таблице параметров, будут взяты из таблицы __index в ее метатете (см. документацию по metatables).

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

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

  • Переменные могут быть сделаны для принятия нескольких имен
  • Позиционные переменные и переменные ключевого слова могут быть вкраплены - и определение обоих может привести к приоритету (или вызвать ошибку).
  • Могут быть сделаны переменные без позиционирования с ключевым словом, а также безымянные позиции, относящиеся только к позиции
  • Строгое построение таблицы может быть выполнено путем разбора строки
  • Список аргументов может быть использован дословно, если функция вызывается с чем-то отличным от 1 таблицы

Некоторые полезные функции для записи переводчиков аргументов: unpack (переход на table.unpack в 5.2), setfenv (устаревший в 5.2 с новой конструкцией _ENV) и select (который возвращает одно значение из списка заданных аргументов или длины списка с помощью '#').

Ответ 2

По-моему, нет другого пути. Это просто менталитет Lua: без излишеств, и кроме синтаксического сахара, нет избыточных способов делать простые вещи.

Ответ 3

Технически, там b = b == nil and 7 or b (который следует использовать в случае, когда false является допустимым значением, поскольку false or 7 оценивается до 7), но это, вероятно, не то, что вы ищете.

Ответ 4

Единственный способ, который я нашел до сих пор, имеет смысл сделать следующее:

function new(params)
  params = params or {}
  options = {
    name = "Object name"
  }

  for k,v in pairs(params) do options[k] = v end

  some_var = options.name
end

new({ name = "test" })
new()