返回多个值的函数 Lua

我想问一下像 pairs() 这样的函数。这样的函数返回多个值,像这样:

function foo()
     x = bar()
     y = x*2
     return x, y
end

x, y = foo()

有没有一种方法可以只获取第二个值而不必理会第一个值?为什么这比简单地返回一个表更可取?

我觉得这个问题在这个网站上可能已经存在,但我找不到它。如果这是重复的,请原谅我。

点赞
用户6879826
用户6879826

使用 Underscores

在 Lua 中,通过使用下划线来丢弃不需要的值是惯用法:

_, y = foo()

当你在源代码中遇到类似 x, y = foo() 的语句时,你期望 xy 都会被使用,但使用下划线的约定表明分配给 _ 的值是不需要的,并且不会被使用。

这是最常见的方法,也是在 Programming in Lua 中最常使用的方法。这个习惯用法经常出现在使用迭代器的循环中。例如,ipairs 迭代器函数返回一个索引和一个值,但你可能只对值感兴趣。这种情况的通常习惯用法如下:

for _, v in ipairs(t) do
   -- 一些使用 v 的操作
end

使用 select

select 函数接受一个起始参数,可以是数字或字符串 "#",和任意数量的其他参数。当起始参数是数字 N 时,从第 N 个参数开始的 所有 额外参数都会被返回。由于 Lua 会丢弃未分配的值,因此这可以用来选择一个参数:

y = select(2, foo())

OP 示例函数返回两个值,但对于返回两个以上的值的函数:

y, z = select(2, bar())

_, y, z = bar()

都将 bar 的第二个和第三个返回值分配给 yz

在我看来,下划线方法更简洁明了。使用 select 还会增加一个附加的函数调用开销。当你想要编程选择一个返回值时,使用 select 会更有意义。选择哪种方法在很大程度上取决于个人喜好。

将返回值包装在一个表中

有时将多个返回值包装在一个表中是有意义的,但作为一般规则,这是一个坏主意。在函数内部将值包装在表中意味着必须创建一个新表,这需要时间;在循环中,这可能意味着代码明显变慢。

你可能有一个情况,希望通过返回一个表来澄清代码,例如一个返回某些数据的平均值、中位数和众数的函数 stats。在这种情况下,你可能希望将这些统计数据收集到一个表中,而不是作为单独的值返回。

如果从函数返回的值可以理解为一张表,请返回一张表。

最后的思考

使用最清晰的方法来编写代码。在我的看法中,下划线方法是默认的方式。如果你有使用其他方法的充分理由,请随心所欲地使用。

2020-07-23 00:01:06
用户4515989
用户4515989

你可以使用内置的 select 函数来实现:

function test()
    return "Hello", "World"
end

local x = select(2, test())
print(x) -- 输出 World

这也在官方文档中有所提及。

2020-07-23 00:17:07
用户11740758
用户11740758

你好

我喜欢为多个结果返回表格,就像debug.getinfo() 或其他函数一样。

several_results=function() return {os.date(), os.time()} end

tab=several_results()

print(#tab) -- 有多少个键?

print(tab[1], tab[2]) -- 两个值都输出

print(tab[2]) -- 只获取第二个键的值

print(tab[#tab]) -- 获取最后一个键的值

-- 进行简单迭代 ...
for incr=1,#tab do print(tab[incr]) end

但是你必须注意一个表的长度 ( # ) 取决于其内容。 命名的键可以通过点来访问,但不能进行计数。

tab={}
tab['name']='Arthur Dent'
print(#tab, tab.name)
-- 输出: 0 Arthur Dent
-- 零和负数同样适用
tab={[0]=0,[-1]=-1}
print(#tab, tab[0], tab[-1])
-- 输出: 0 0 -1
2020-07-23 10:07:35