2017-05-04 84 views
1

我一直在学习LUA似乎并不能作简单的实现这个二叉树的工作......LUA不修改函数参数

function createTree(tree, max) 
    if max > 0 then 
     tree = {data = max, left = {}, right = {}} 
     createTree(tree.left, max - 1) 
     createTree(tree.right, max - 1) 
    end 
end 

function printTree(tree) 
    if tree then 
     print(tree.data) 
     printTree(tree.left) 
     printTree(tree.right) 
    end 
end 

tree = {} 
createTree(tree, 3) 
printTree(tree) 

程序刚刚执行后返回零。我在网上搜索了解如何在lua中传递参数(如果是通过引用或通过值),并发现某些类型通过引用(如表和函数)传递,而其他类型则通过值传递。尽管如此,我在将全局变量“tree”传递给“createTree”函数之前创建了一个表格,为了同样的目的,我甚至将“left”和“right”初始化为“createTree”中的空表格。我究竟做错了什么?

回答

1

可以肯定的是,对于大多数情况下lua通过价值传递论据。但对于数字以外的任何对象(数字实际上不是对象),“值”实际上是指向所述对象的指针。

当你做这样的事情a={1,2,3}b="asda"右边的值是动态分配的地方,和ab只有获得这些地址。因此,当你通过a的功能fun(a),指针被复制到内部功能的新的变量,但a本身没有受到影响:

function fun(p) 
    --p stores address of the same object, but `p` is not `a` 
    p[1]=3--by using the address you can 
    p[4]=1--alter the contents of the object 
    p[2]=nil--this will be seen outside 

    q={} 
    p={}--here you assign address of another object to the pointer 
    p=q--(here too) 
end 

功能也是通过指针向他们表示,你可以使用debug库为了修改函数对象(例如更改upvalues),这可能会影响函数的执行方式,但是,再次,您不能更改外部引用指向的位置。

字符串是不可变的对象,您可以将它们传递给它们,还有一个库可以为它们做些东西,但该库中的所有函数都会返回新的字符串。因此,如果您尝试在函数内部使用“asda”字符串执行某些操作,那么再次从b="asda"开始,外部变量b不会受到影响。

+0

你的回答非常明确,让我明白我的错误。基本上,我的误解是REFERENCE中传递了“对象”变量(比如字符串和表),但是现在我明白它们是由指针表示并且通过值传递的。这使得函数可以改变它所指向的数据,但不是指针本身的地址(例如,如果我理解正确的话,通过值传递指针到C/C++函数)。其他答案使我接近这个结论,但它是你的,摧毁了所有的疑惑。谢谢 :) – Dincio

5

在Lua中,参数是按值传递的。分配给参数不会改变原始变量。

试试这个:

function createTree(max) 
    if max == 0 then 
     return nil 
    else 
     return {data = max, left = createTree(max-1), right = createTree(max-1)} 
    end 
end 
+0

我承认这不是让我理解我的错误的答案,但看到你如何创建那棵树仍然是有帮助的。我从来没有想过这样做,而且它比我想出的还要简单和优雅!不过,你的版本不会利用尾递归吗? – Dincio

6

这可能是需要通过一个新的表不能初始化,但只设置其值。

function createTree(tree, max) 
    if max > 0 then 
     tree.data = max 
     tree.left = {} 
     tree.right = {} 
     createTree(tree.left, max - 1) 
     createTree(tree.right, max - 1) 
    end 
end 
+0

虽然这个答案让我接近了解它并不完整的问题。谢谢反正提供必要的信息来规避我的问题:) – Dincio