2015-12-20 41 views
-1
function bar(w) 
    w = 1 
end 
a = 2 
bar(a) 
print(a) -- => 2 

下一个是工程,但它不是参数。如果变量是遗产,则不能更改函数中的变量

function test() 
    a = 1 
end 
a = 2 
test(a) 
print(a) -- => 1 

如何更改函数体中的变量变量是参数?

+3

这是因为在Lua中,你*传递了价值。*这意味着你只是编辑参数的**副本,而不是实际的参数本身。您可能会发现这个讨论很有用:http://lua-users.org/lists/lua-l/2004-06/msg00257.html –

+0

答案是对Lua的很好的解释。但是,您可能会注意到“按价值传递”,“按引用传递”等术语中的一些变化。它们最适合需要的环境,不同的语言有不同的需求。 [更多研究](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_reference) –

回答

3

在Lua中,大部分值都是按值传递的。当你将它们传递给一个函数时,意味着你的函数仅仅是一个副本。这包括字符串,数字,零和布尔值。但是还有其他两种数据类型(不包括userdatas)。

表和函数。

它们是通过引用。这意味着,您可以编辑这两种数据类型,并且它将是'永久的',因为您有一个对原始值的引用。

让我们从表格开始。在你的函数,如果我们传递一个表,你可以改为编辑属性:

function Change(x) 
    x.val = 5 
end 

a = {val=2} 
Change(a) 
print(a.val) 

现在,这是微不足道的,所以我不会费心去解释它是如何工作的。

接下来让我们使用一个函数。但是...怎么样?你如何编辑一个函数?

嗯,你看,功能有这些令人惊叹的东西被称为'upvalues'。出它的范围当地的价值观,所以我们可以写一个简单的get/set函数,就像这样:

function Change(x) 
    x("set", 5) 
end 

do 
    local val = 2 
    function a(method, v) 
     if method == "set" then 
      val = v 
     elseif method == "get" then 
      return val 
     end 
    end 
end 
Change(a) 
print(a("get")) 

当你与集调用,你给局部变量之外它的范围(它的外面范围,以便它不是不重置每个电话)一个新的价值。并得到将返回它。

但是,如果这不实际。那么如果你想修改全局变量,你可以使用_G。而不是传递值本身,将该变量作为字符串传递。这将允许我们对变量进行索引。与传递参考一样好,缺点如何?它不会与当地人合作。

function Change(x) 
    _G[x] = 5 
end 

a = 2 
Change('a') 
print(a) 

我希望我的回答帮你!

+0

>你可以使用_G; 所以没有办法为当地人? – Parki

+0

@Parki正如我在我的回答中所提到的,只有当你想改变全局变量时,_G才有用。你不能为当地人操纵它,但幸运的是我提到了其他两种可以在本地使用的方法。 – warspyking

3

由于在评论lua值中指示的数字向量通常按值传递。所以你不能这样做。

但是,表格通过引用传递。 (有关此更多的讨论,请参见在LUA手册中2.2 Values and Types。)

所以,如果你通过表格插入功能,您可以修改值表。

function bar(tab) 
    tab.w = 1 
end 
local t = {w = 2} 
bar(t) 
print(t.w) -- => 1 
+3

*所有* Lua值是按值传递的 - 表引用也不例外。 – siffiejoe

+0

@siffiejoe尽管表的“值”是对表的引用。尽管语义不同,但它仍然是一个有意义的区别。 –