2017-01-20 15 views
1

Скажем, я делаю unpack(4) или unpack("hello world"). Есть ли какое-нибудь неожиданное поведение?Есть ли причина не распаковывать простые значения в Lua

Причина что-то вроде этого:

function a(bool) 
    if bool then 
    return {1, 2}, "foo" 
    else 
    return 1, "foo" 
    end 
end 

function b(x, z) 
end 

function b(x, y, z) 
end 

i, j = a(???) 
b(unpack(i), j) -- is this ok? 
+1

это проложило вам путь вы можете просто запустить код и посмотреть, что происходит, вместо того, чтобы спрашивать, что происходит? гораздо лучший способ узнать – Piglet

+1

'b (unpack (i), j)' - плохой пример: результат 'unpack (i)' будет скорректирован до одного значения. –

+1

Не самый простой способ просто вернуть таблицу во всех случаях? Итак, если есть одно значение, которое нужно вернуть, сделайте так: return {1}, "foo" ' – tonypdmtr

ответ

2

unpack(4) вызовет ошибку

попытка получить длину числового значения

unpack("hello world") вернется

ноль ноль ноль ноль ноль ноль ноль ноль ноль ноль ноль

так что это не очень полезно, как хорошо.

unpack предназначен для распаковки столов. Если вы хотите работать с последней версией Lua вы заметите, что теперь table.unpack()

Другие проблемы с вашим кодом:

Lua не поддерживает перегружать функции. Функции - это переменные.

Вы пишете:

function b(x, z) 
end 

function b(x, y, z) 
end 

Первое определение теряется, как только второе определение обрабатывается. Если вы используете другое обозначение, это будет более ясно. Ваш код эквивалентен

b = function (x, z) 
end 

b = function (x, y, z) 
end 

, и я думаю, вы согласитесь, что после

b = 3 
b = 4 

b будет 4. Тот же принцип ...

+1

Хотя я вижу, что вы делаете о переписывании определения функции, я не согласен с тем, что Lua не поддерживает функции перегрузки, так как это дает тот же эффект, по-другому. Например, разрешение разрешить произвольное число или тип аргументов эффективно работает одинаково. В вашем примере «функция b (x, y, z)» может быть выполнена как «функция b (x, y)», когда 'z' является' nil'. И, если дополнительная версия функции должна быть определена позже (т. Е. Отдельно), вы всегда можете использовать исходную функцию следующим образом: 'local b = function (x, y, z) b (x , y) end' – tonypdmtr

+0

Исправления: 1) функция - это значение, а не переменная. Значение функции, как и любое другое значение, «потеряно», если у него нет ссылок на него. 2) определение функции - это выражение, которое выдает значение функции. Это код, который никогда не может быть потерян. –

+1

@ tonypdmtr «перегрузка» имеет смысл только тогда, когда есть фаза разрешения привязки (например, компилятором). В Lua имя относится только к одному человеку в одно и то же время и в любом месте. Каждое значение функции можно вызывать с любым количеством параметров в любое время. Он касается тех, которые он хочет, каким бы он ни хотел и игнорирует остальных. –

2

Вы можете изменить стандартную функцию unpack для получить желаемое поведение:

local old_unpack = table.unpack or unpack 

local function new_unpack(list, ...) 
    if type(list) ~= "table" then 
     list = {list} 
    end 
    return old_unpack(list, ...) 
end 

table.unpack = new_unpack 
unpack = new_unpack 

-- Usage: 
print(unpack(4)) 
print(unpack("hello world")) 
print(unpack(nil)) -- ops! nothing is printed!