Lua与表的多重赋值

时间:2015-08-03 05:55:42

标签: lua

此代码:

function foo()
    return 1, 2, 3
end

bar = {}

bar = {a, b, c = foo()}

产生

bar.a = nil
bar.b = nil
bar.c = 1

如何编写以便获得:

bar.a = 1
bar.b = 2
bar.c = 3

无需写下这样的内容:

function foo()
    return 1, 2, 3
end

bar = {}
a, b, c = foo()

bar = {a = a, b = b, c = c}

4 个答案:

答案 0 :(得分:5)

bar = {}
bar.a, bar.b, bar.c = foo()

答案 1 :(得分:5)

BLUF

没有直接或优雅的方式来做到这一点。你必须像这样手动完成

local r = { f() }           --> store all returned values in r
local bar = { }
local c = string.byte 'a'   --> start with 'a'
for _, v in ipairs(r) do
   local t = string.char(c)
   bar[t] = v               --> assign each value to respective letter
   c = c + 1
end

如果你有a, b, c = foo(),你将获得分配给这三个变量的所有三个值。但是,你已经

bar = { a, b, c = foo() }

table constructor expression将被解释为键abc被插入到表中,只有最后一个键具有关联值(旁边:没有关联值的键被视为nil;因此永远不会插入ab。由于只有一个变量可以取foo返回的值,除了它返回的其他所有内容都将被丢弃。

或者,bar = { foo() }会将foo返回的所有值分配为bar的数组值。但是,访问这些内容的关键是[1][2]等,而不是'a''b'等。

请阅读以下内容,了解何时丢弃返回的值以及何时不丢弃。

<强> TL; DR 仅当函数调用是表达式列表中的最后一个/唯一表达式时,才会保留所有返回值;除了第一个之外的其他地方都被丢弃了。

函数调用作为语句

在Lua中,当我们从函数返回多个结果时,如果函数调用本身是一个语句,则所有结果都会被丢弃。

foo()

将丢弃所有三个返回值。

表达式

中的函数调用

如果它在表达式中使用,则只保留第一个,其他所有内容都将被丢弃。

x = foo() - 1
print(x)        -- prints 0; the values 2, 3 are discarded

表达式列表中的函数调用

仅当调用显示为表达式列表中的最后/唯一项目时,才会保留返回的整个值列表。这样的表达列表出现在Lua的四个地方:

  1. 多项作业

    E.g。 local a, b, c, d = 0, f()。此处bcd分别获得值123

  2. 表构造函数

    E.g。 local t = { 0, f() }f返回的所有值都会在第一个t之后放入0

  3. 函数调用参数

    E.g。 g(a, f())g会收到4个而不是2个参数。 a以及来自f的三个值。

  4. return声明

    E.g。 return 'a', f()。字符串'a'的附加内容,f返回的所有值都将在主叫端收到。

  5. 在所有这些情况下,如果f不是列表中的最后一个表达式或者不是唯一的表达式,那么它返回的所有值除了第一个表达式都会被丢弃。

    多个赋值语句

    在多重赋值语句中,当分配的值的数量小于变量的数量时,额外的变量将分配给nil。如果是另一种方式,即如果变量的数量较少,则会丢弃额外的值。

    a, b, c = 1, 2         -- a = 1, b = 2, c = nil
    a, b, c = 1, 2, 3, 4   -- 4 gets discarded
    

答案 2 :(得分:0)

bar = {}
local abc = foo()
bar.a, bar.b, bar.c = abc, abc, abc

bar.a, bar.b, bar.c = foo()仅将bar.a设置为foo(),其他两个将分别设置为nil,因为它们分别被设置为第二和第三值,而您仅给出了一个值。

答案 3 :(得分:0)

如果可以的话,让foo()返回正确格式的表。

function foo()
    return {a = 1, b = 2, c = 3}
end

bar = foo()