Lua 多重赋值表 [英] Lua multiple assignment with tables

查看:19
本文介绍了Lua 多重赋值表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此代码:

函数 foo()返回 1、2、3结尾条 = {}bar = {a, b, c = foo()}

产生:

bar.a = nilbar.b = 零bar.c = 1

这怎么写才能让你得到:

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

不必写这样的东西:

函数 foo()返回 1、2、3结尾条 = {}a, b, c = foo()bar = {a = a, b = b, c = c}

解决方案

BLUF

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

local r = { f() } -->将所有返回值存储在 r 中当地酒吧 = { }本地 c = string.byte 'a' -->以'a'开头对于 _, v in ipairs(r) 做本地 t = string.char(c)bar[t] = v -->将每个值分配给相应的字母c = c + 1结尾

如果你有 a, b, c = foo() 你会得到分配给三个变量的所有三个值.但是,您已经

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

这个表构造函数表达式将被解释为键 abc 被插入到表中,只有最后一个键具有关联值(除了:没有关联值的键被视为 nil;因此 ab 永远不会被插入).由于只有一个变量来获取 foo 返回的值,除了第一个它返回的其他所有内容都被丢弃.

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

阅读以下内容,了解返回值何时被丢弃,何时不被丢弃.


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

函数调用作为语句

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

foo()

将丢弃所有三个返回值.

表达式中的函数调用

如果用在表达式中,只保留第一个,其他的都丢弃.

x = foo() - 1打印(x)——打印0;值 2, 3 被丢弃

表达式列表中的函数调用

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

  1. 多重分配

    例如局部 a, b, c, d = 0, f().这里 b, c, d 得到值 1, 2, >3 分别.

  2. 表构造函数

    例如local t = { 0, f() }.f 返回的所有值都放在 t 中,紧跟在第一个 0 之后.

  3. 函数调用参数

    例如g(a, f()).g 将接收 4 个,而不是 2 个参数.af 中的三个值.

  4. return 语句

    例如返回'a', f().除了字符串'a'f返回的所有值都将在调用端接收.

在所有这些情况下,如果 f 不是作为列表中的最后一个表达式出现或者不是唯一的表达式,那么它返回的除第一个之外的所有值都将被丢弃.>

多重赋值语句

在多重赋值语句中,当赋值的个数小于变量个数时,多余的变量赋值为nil.当情况相反时,即如果变量的数量较少,则丢弃额外的值.

a, b, c = 1, 2 -- a = 1, b = 2, c = nila, b, c = 1, 2, 3, 4 -- 4 被丢弃

This code:

function foo()
    return 1, 2, 3
end

bar = {}

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

produces:

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

How can this be written so that you get:

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

without having to write something like this:

function foo()
    return 1, 2, 3
end

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

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

解决方案

BLUF

There's no straight forward or elegant way to do this. You'll have to do it manually like this

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

If you'd had a, b, c = foo() you'd get all the three values assigned to the three variables. However, you've

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

This table constructor expression will get interpreted as the keys a, b, c getting inserted into the table, with only the last key having an associated value (aside: keys with no associated value are taken as nil; hence a and b never get inserted). Since there's only one variable to take the values returned by foo, except the first everything else it returns are discarded.

Alternatively bar = { foo() } will assign all values returned by foo as array values of bar. However, the key to access these would [1], [2], etc. and not 'a', 'b', etc.

Read below to know when the returned values get discarded and when they don't.


TL;DR All returned values are retained only when the function call is the last/only expression in a list of expressions; elsewhere all except the first are discarded.

Function call as a statement

In Lua, when we return multiple results from a function, all of them get discarded if the function call is a statement by itself.

foo()

will discard all three return values.

Function call in an expression

If it's used in an expression, only the first will be retained and everything else will be discarded.

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

Function call in an expression list

The entire list of values returned is retained only when the call appears as the last/only item in a list of expressions. Such list of expressions occur at four places in Lua:

  1. Multiple assignment

    E.g. local a, b, c, d = 0, f(). Here b, c, d get the values 1, 2, 3 respectively.

  2. Table constructor

    E.g. local t = { 0, f() }. All values returned by f are put into t following the first 0.

  3. Function call arguments

    E.g. g(a, f()). g would receive 4, not 2, arguments. a and the three values from f.

  4. return statement

    E.g. return 'a', f(). Additional to the string 'a', all values returned by f will be received at the calling end.

In all these situations, had f appeared not as the last expression in the list or wasn't the only expression, then all values it returned except the first would've been discarded.

Multiple assignment statement

In the multiple assignment statement, when the number of values assigned is lesser than number of variables, the extra variables be assigned to nil. When it's the other way around i.e if the number of variables are lesser, the extra values are discarded.

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

这篇关于Lua 多重赋值表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆