多返回值

本文详细介绍了Lua函数如何返回多个结果值,并通过多个示例展示了如何在不同场景下利用这些多返回值特性,包括作为表达式、参数调用和表初始化时的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 5.1 多返回值

 

Lua函数可以返回多个结果值,比如string.find,其返回匹配串“开始和结束的下标”(如果不存在匹配串返回nil)。

s, e = string.find("hello Lua users", "Lua")

print(s, e)       --> 7  9

Lua函数中,在return后列出要返回的值得列表即可返回多值,如:

function maximum (a)

    local mi = 1             -- maximum index

    local m = a[mi]          -- maximum value

    for i,val in ipairs(a) do

       if val > m then

           mi = i

           m = val

       end

    end

    return m, mi

end

 

print(maximum({8,10,23,12,5}))     --> 23   3

Lua总是调整函数返回值的个数以适用调用环境,当作为独立的语句调用函数时,所有返回值将被忽略。假设有如下三个函数:

function foo0 () end                   -- returns no results

function foo1 () return 'a' end        -- returns 1 result

function foo2 () return 'a','b' end    -- returns 2 results

第一,当作为表达式调用函数时,有以下几种情况:

1. 当调用作为表达式最后一个参数或者仅有一个参数时,根据变量个数函数尽可能多地返回多个值,不足补nil,超出舍去。

2. 其他情况下,函数调用仅返回第一个值(如果没有返回值为nil)

x,y = foo2()             -- x='a', y='b'

x = foo2()               -- x='a', 'b' is discarded

x,y,z = 10,foo2()        -- x=10, y='a', z='b'

 

x,y = foo0()             -- x=nil, y=nil

x,y = foo1()             -- x='a', y=nil

x,y,z = foo2()           -- x='a', y='b', z=nil

 

x,y = foo2(), 20         -- x='a', y=20

x,y = foo0(), 20, 30     -- x='nil', y=20, 30 is discarded

第二,函数调用作为函数参数被调用时,和多值赋值是相同。

print(foo0())            -->

print(foo1())            --> a

print(foo2())            --> a   b

print(foo2(), 1)         --> a   1

print(foo2() .. "x")     --> ax

第三,函数调用在表构造函数中初始化时,和多值赋值时相同。

a = {foo0()}             -- a = {}    (an empty table)

a = {foo1()}             -- a = {'a'}

a = {foo2()}             -- a = {'a', 'b'}

 

a = {foo0(), foo2(), 4}  -- a[1] = nil, a[2] = 'a', a[3] = 4

另外,return f()这种形式,则返回“f()的返回值”:

function foo (i)

    if i == 0 then return foo0()

    elseif i == 1 then return foo1()

    elseif i == 2 then return foo2()

    end

end

 

print(foo(1))        --> a

print(foo(2))        --> a  b

print(foo(0))        -- (no results)

print(foo(3))        -- (no results)

可以使用圆括号强制使调用返回一个值。

print((foo0()))      --> nil

print((foo1()))      --> a

print((foo2()))      --> a

一个return语句如果使用圆括号将返回值括起来也将导致返回一个值。

函数多值返回的特殊函数unpack,接受一个数组作为输入参数,返回数组的所有元素。unpack被用来实现范型调用机制,在C语言中可以使用函数指针调用可变的函数,可以声明参数可变的函数,但不能两者同时可变。在Lua中如果你想调用可变参数的可变函数只需要这样:

f(unpack(a))

unpack返回a所有的元素作为f()的参数

f = string.find

a = {"hello", "ll"}

print(f(unpack(a)))      --> 3  4

预定义的unpack函数是用C语言实现的,我们也可以用Lua来完成:

function unpack(t, i)

    i = i or 1

    if t[i] then

       return t[i], unpack(t, i + 1)

    end

end

 


相关链接:
lua程序设计目录 - 中国lua开发者 - lua论坛

### C++ 中实现返回值函数的方法 #### 方法1:自定义结构体作为返回类型 通过创建一个包含个数据成员的结构体来封装返回值。这种方式直观明了,适合于逻辑上紧密关联的数据。 ```cpp struct Result { int code; std::string message; }; Result process() { return {0, "success"}; } ``` 这种方法使得接口清晰易懂[^2]。 #### 方法2:利用引用传递参数 可以将额外的结果变量作为引用类型的形参传入,在函数内部对其赋值从而达到返回个值的效果。 ```cpp void divide(int a, int b, double& quotient, bool& success) { if (b != 0) { quotient = static_cast<double>(a) / b; success = true; } else { success = false; } } int main() { double q; bool s; divide(8, 4, q, s); // 使用q和s... } ``` 此方式简单直接但可能影响代码可读性和安全性。 #### 方法3:采用 `std::tuple` 返回三个及以上返回值 当需要返回超过两个不同类型或者数量不确定的结果时,可以考虑使用标准库中的元组类模板。 ```cpp #include <iostream> #include <tuple> std::tuple<int, char, float> getValues() { return std::make_tuple(42, 'A', 3.14f); } int main() { auto [num, ch, flt] = getValues(); std::cout << num << ", " << ch << ", " << flt << '\n'; } ``` 这种方案灵活性高,适用于复杂场景下的需求。 #### 方法4:借助 `std::pair` 处理双返回值情况 如果只需要同时返回两份信息,则可以直接选用成对组合的对象形式。 ```cpp #include <utility> std::pair<std::string, size_t> findWord(const std::vector<std::string>& words, const std::string& target) { for (size_t i = 0; i < words.size(); ++i) if (words[i] == target) return {target, i}; throw std::runtime_error("not found"); } ``` 上述四种技术各有优劣,开发者可以根据具体应用场景和个人偏好做出合理的选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值