2017-05-04 118 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