LINUX.ORG.RU

Для чего в lua существует arg.n?

 


0

2
function test(op, ...)
	if op == "sum" then
		local acc = 0
		for k, i in pairs(arg) do
			acc = acc + i
		end
		return acc
	elseif op == "mult" then
		local acc = 1
		for k, i in pairs(arg) do
			acc = acc * i
		end
		return acc
	end
end

print(test("sum", 1, 2))
print(test("sum", 1, 2, 3))
print(test("mult", 2, 3))
print(test("mult", 2, 3, 4))
sevenredlines ~/lua: lua test2.lua
5
9
12
72

Назовите мне хоть одну причину, по которой тот, кто придумал arg.n, тогда как уже существует #arg, не идиот.

вобщем так..

можешь пожалуйста подставить nil в серидину аргументов (между аргументами) .. что получится?

user_id_68054 ★★★★★
()
Ответ на: комментарий от user_id_68054
print(test("sum", 1, 2, 3))
print(test("sum", 1, nil, 2, 3))
sevenredlines ~/lua: lua test2.lua
9
10

кстати, getmetatable(arg) == nil.

sevenredlines
() автор топика

и пожалуйста ещё проделай другой эксперимент: что будет если последний аргумент будет nil ? (а первые два аргумента будут нормальными, не nil)

user_id_68054 ★★★★★
()
Ответ на: комментарий от user_id_68054
print(test("sum", 1, 2))
print(test("sum", 1, 2, nil))
sevenredlines ~/lua: lua test2.lua
5
6
sevenredlines
() автор топика

погодь погодь

а ты можешь просто сделать функцию:

local function test_A(op, ...)
    print(op)
    print(#arg)
end

local function test_B(op, ...)
    print(op)
    print(arg.n)
end

и проверить например

test_A('фигня', 1,2,3)
test_B('фигня', 1,2,3)
test_A('фигня', 1,nil,3)
test_B('фигня', 1,nil,3)
test_A('фигня', 1,2,nil)
test_B('фигня', 1,2,nil)

ато твой пример слишком сложный :-)

(то если я допустил ошибку в коде — то исправь там сам.. ато я на глаз делаю :))

user_id_68054 ★★★★★
()
Ответ на: комментарий от user_id_68054
local function test_A(op, ...)
    print(op .. " " .. #arg)
end

local function test_B(op, ...)
    print(op .. " " .. arg.n)
end

test_A('test', 1,2,3)
test_B('test', 1,2,3)
test_A('test', 1,nil,3)
test_B('test', 1,nil,3)
test_A('test', 1,2,nil)
test_B('test', 1,2,nil)
sevenredlines ~/lua: lua test3.lua 
test 3
test 3
test 3
test 3
test 2
test 3
sevenredlines
() автор топика
Ответ на: комментарий от user_id_68054

The Length Operator (#) metamethod is given, the length of a table t is only defined if the table is a sequence, that is, the set of its positive numeric keys is equal to {1..n} for some non-negative integer n. In that case, n is its length. Note that a table like: {10, 20, nil, 40} is not a sequence, because it has the key 4 but does not have the key 3. (So, there is no n such that the set {1..n} is equal to the set of positive numeric keys of that table.) Note, however, that non-numeric keys do not interfere with whether a table is a sequence.

anonymous
()

Решетка в lua - убербыстрое определение длины таблицы при соблюдении условий, что её индексы - положительные числовые последовательности {1,2,..,n} без nil. При использовании данных индексов реализована более быстрая работа с таблицами и обращение к элементам (использование таблиц как массивов). В ином случае необходимо вести свой счётчик или перебирать все индексы таблицы через pairs.

anonymous
()
Ответ на: комментарий от anonymous

Решетка в lua - убербыстрое определение длины таблицы при соблюдении условий...

получается ли что Решётка (#) — *определяет* длину, а arg.n уже заранее хранит\передаёт длину (без всякого определения) ?

но хотя думаю что lua это не тот язык где программист должен пытаться заоптимизировать свой код на каждой «съэкономленной спичке» :-)

user_id_68054 ★★★★★
()
Ответ на: комментарий от user_id_68054

именно так же. Проблема собственно в том, что arg.n делает невозможным перебор через for k, v in pairs(arg). Но я обнаружил такой вариант: for k, v in pairs({...}).

sevenredlines
() автор топика
Ответ на: комментарий от sevenredlines

можно скопировать таблицу аргументов с помощью table.pack()

function func1(a,b,...) 
    local arg = table.pack(...)
    print(arg.n,arg[1],arg[2],arg[3])
end

anonymous
()
Ответ на: комментарий от sevenredlines

arg.n делает невозможным перебор через for k, v in pairs(arg)

да, похоже arg.n намекает нам на неуклюжую конструкцию:

for k = 1, arg.n do
  v = arg[k]
  
  -- что-то тут --
  
end

а вообще в книжке щаз прочитал, что типа вся суть arg это local arg = table.pack(...)

user_id_68054 ★★★★★
()
Последнее исправление: user_id_68054 (всего исправлений: 3)
Ответ на: комментарий от sevenredlines

Но я обнаружил такой вариант: for k, v in pairs({...}).

но ведь не может быть такого чтобы в конце цикла for последние значения от pairs оказались бы <какое-то-число> и nil ?

то есть конструкция for k, v in pairs({...}) должна же в точности вести ведь себя точно также как и for k, v in pairs(arg) ? (так как в обоих случаях используется функция pairs, которая имеет это ограничение на невозможнсть nil концовки)

user_id_68054 ★★★★★
()
Последнее исправление: user_id_68054 (всего исправлений: 1)
Ответ на: комментарий от user_id_68054

то есть конструкция for k, v in pairs({...}) должна же в точности вести ведь себя точно также как и for k, v in pairs(arg) ?

arg, как ты уже заметил это table.pack({...}), который добавляет еще одно дополнительное именованное поле 'n' в таблицу.

(так как в обоих случаях используется функция pairs, которая имеет это ограничение на невозможнсть nil концовки)

Ты путаешь с функцией ipairs - которая бегает по массивной части таблицы, pairs проитерирует все значения, включая nil в любом месте.

Vovka-Korovka ★★★★★
()
Ответ на: комментарий от Vovka-Korovka

Извиняюсь, напутал сам, таблицы в луа не различают случаи, когда ключа нету или когда по ключу сохранили nil.

Vovka-Korovka ★★★★★
()
15 ноября 2016 г.
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.