【问题标题】:Lua: Functions with Multiple ReturnsLua:具有多个返回的函数
【发布时间】:2014-06-23 15:49:11
【问题描述】:

由于某种原因,我在思考在函数中使用参数的适当方式以及稍后调用该函数并返回正确参数时遇到了问题。如果我想使用一个函数来找出使用的形状类型。此形状包含我想使用的形状缩写后的数据,例如 Sq105428。快速示例:

function Shape(...) -- can I use "..." or should I put "Type, Shape_data, Shape_side" inside?
    Shapes = {["Tri"] = 3, ["Sq"] = 4, ["Po"] = 5, ["Hex"] = 6}
        for k,v in pairs (Shapes) do
            Type = string.match(input, k..".*")
                if Type == k then
                    Shape_data = string.match(input,Type.."(.*)")
                    Shape_side = v
                end
        end
        return Type, Shape_data, Shape_side -- can I call for these later in my code?
end

稍后,我会调用返回的变量并使用它们。我在理解如何正确调用返回的变量时遇到问题。在我的代码中,我想采用这三个变量并在整个代码中使用它们。我该如何正确地召唤他们?

我明白:

function f() body end  ==  f = function() body end -- pg 15 PIL and helps me to understand

我也了解如何正确使用数学函数,例如:

function exp (x)
    print x^2
end

print exp(4) -- yields 16

但是,如果我想在代码的不同点使用这三个变量,那么调用我的示例的适当方法是什么?我在完全理解如何正确构造函数调用并稍后调用它时遇到问题。是不是很简单:

Example = math.floor(math.pi * Shape(Shape_side) + 0.5) -- is this ok?

感谢您的帮助。

【问题讨论】:

    标签: function lua multiple-results


    【解决方案1】:

    这并不完全正确。首先,您在函数中设置全局变量,但如果它们只是用于函数的临时变量,则绝对应该使用局部变量。

    现在回到你的功能:

    function(...)
    

    表示您希望在函数中接收可变数量的参数,而无需将 tchem 分配给任何变量。要使用这些参数,您需要将它们分配给命名变量,如下所示:

    local side, type, data = ...
    

    或者使用select函数。

    您真正想要的(我猜是您对math.floor 的调用)只是告诉函数应该返回哪些数据。为此,您不需要多个参数,只需要一个参数:

    function shape(what)
    

    然后根据what 中的内容,仅返回该数据,或者(例如)如果未提供内容,则返回所有需要的数据:

    if what == "side" then
        return side
    elseif what == "whatever" then
        return whatever
    elseif not what then
        return side, whateveer
    else
        return nil
    end
    

    当然,这只是一个例子。要使用多个返回值,您需要将它们存储在某个地方:

    local side, whatever = shape() -- returns multiple values, because `what` is nil
    local result = math.floor(math.pi * side + 0.5)
    

    关于你的功能的效率:

    看起来它充其量是次优的。每次调用该函数时,它都会解析提供的输入。所以如果你想得到数据,它必须越过input,如果你想得到形状的一面,它必须再次越过input。每次调用该函数时,都会重新声明一个全局 Shapes

    如果函数根本不操作全局变量也是最好的(例如,除了调用一些其他全局函数)。它使它们更加通用(例如从提供的变量解析输入,而不是从全局输入)。

    我可能误解了你的功能的目的,但我会有所不同:

    local Shapes = {["Tri"] = 3, ["Sq"] = 4, ["Po"] = 5, ["Hex"] = 6} -- create a closure
    
    function Shape(input)
        for k, v in pairs(Shapes) do
            local type = string.match(input, k) --I thinkg with your match you'd never get past the next line
            if type then --no need to do the comparison, as type would be nil if no match is found
                return k, string.match(input, k.."(.*)"), v
            end
        end
        return nil --erroneous input, no match found
    end
    

    现在您将存储您需要的所有数据,然后简单地使用它,而无需重新调用函数并再次解析输入:

    local type, data, side = Shape(userInput)
    

    或者更好的是,让函数返回一个表并以更好的方式访问数据:

    ...
    if type then --no need to do the comparison, as type would be nil if no match is found
        return {type = k, data = string.match(input, k.."(.*)"), side = v}
    end
    ...
    

    然后将数据存储为:

    local userShape1 = Shape(userInput1)
    local userShape2 = Shape(userInput2)
    --now use the results
    local result1 = math.floor(math.pi * userShape1.side + 0.5)
    local result2 = math.floor(math.pi * userShape2.side + 0.5)
    local dataResult1 = processShapeData(userShape1.data)
    

    现在这比多个本地值慢,但更干净,imo,如果您是 Lua 新手,这很重要。还有一些其他的东西可以使函数更好、更快(比如需要输入以从形状类型开始),但我不会让你厌烦。

    回到你原来的问题,要使用多个返回值,你需要将它们存储在变量中。如果您的函数返回多个值,但您只对一个变量进行赋值,则其余数据将被丢弃:

    local type = Shape(input) --assuming the function returns multiple values, not a table
    

    【讨论】:

    • 我觉得我跑题了,抱歉。
    • @WB 谢谢你的回答。在阅读了几次并与您的回复同时进行了一些研究之后,我相信我对您为什么要这样做有了更好的理解。但我还有另一个问题。如果我将return nil 放在return {...} 之后,为什么nil 不会清除表中的任何返回值?
    • @WB 关于您的答案的最后一个问题。如果我存储的变量位于函数内的无名表中,倒数第二部分让我对存储数据然后使用它有点困惑。如果表没有命名,它会自动变为function_name{} 吗?如果我有多个变量(在我的foo{} 中包含变量的函数之外;我将如何引用它们?例如local side = shape(input)local shapes = shape(input) 等......
    • @Pwrcdr87 我不确定我是否听懂了你的问题。如果一个函数执行return,它将在该行结束执行。因此,您之后放置的所有内容都不会被执行。至于第二部分,如果一个表没有命名,它是一个临时变量。这通常用于返回值并将参数传递给函数。
    • @WB 感谢您的帮助。通过我的回复问题,在您的function Shape(input) 示例中,您有return k, string.match(input, k.."(.*)"), v end end,然后是return nil end。我完全理解return k, string.match(input, k.."(.*)"), v 的原因。但是,如果我以return nil 结束整个函数,在调用时我不会总是收到一个nil 来表示变量的值吗?
    猜你喜欢
    • 2016-09-27
    • 2012-09-30
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    • 2011-11-20
    • 2012-03-17
    • 1970-01-01
    • 2016-11-19
    相关资源
    最近更新 更多