Unpacking problem in Lua
I have the following function unpack()
:
function unpack(t, i)
i = i or 1
if t[i] then
return t[i], unpack(t, i + 1)
end
end
Now I am using it in the following test code:
t = {"one", "two", "three"}
print (unpack(t))
print (type(unpack(t)))
print (string.find(unpack(t), "one"))
print (string.find(unpack(t), "two"))
which outputs:
one two three
string
1 3
nil
What puzzles me is the last line, why is the result nil
?
source to share
If the function returns multiple values, unless it is used as the last parameter, only the first value is accepted.
In your example, string.find(unpack(t), "one")
both string.find(unpack(t), "two")
, "two"
and are dropped "three"
, they are equivalent:
string.find("one", "one") --3
and
string.find("one", "two") --nil
source to share
Lua Pil can say this under 5.1 - Several results :
Lua always adjusts the number of results from a function to the circumstances of the call. When we call a function as an instruction, Lua discards all of its results. When we use the call as an expression, Lua only stores the first result. We get all results only when the call is the last (or only) expression in the list of expressions . These lists appear in four constructs in Lua: multiple assignments, arguments to function calls, table constructors, and return statements.
Here's an example to illustrate:
function foo0 () end -- returns no results
function foo1 () return 'a' end -- returns 1 result
function foo2 () return 'a','b' end -- returns 2 results
x, y = foo2(), 20 -- x='a', y=20
x, y = foo0(), 20, 30 -- x='nil', y=20, 30 is discarded
Yu Hao's answer shows how this applies to your example.
source to share
The unpack function returns multiply parameters, string.find only takes the first parameters (the rest are discarded).
This function unpacks and concatenates all strings, so the output of the function will be the only parameter.
function _unpack(t,char)
return table.concat(t,(char or " "));
end
t = {"one", "two", "three"}
print (_unpack(t))
print (type(_unpack(t)))
print (string.find(_unpack(t), "one"))
print (string.find(_unpack(t), "two"))
Output
one two three
string
1 3
5 7
source to share