2016-01-21 34 views
2

考慮下面的代碼:Bash是否有用於遞歸函數調用的私有堆棧框架?

recursion_test() { 
    local_var=$1 
    echo "Local variable before nested call: $local_var" 

    if [[ $local_var == "yellow" ]]; then 
     return 
    fi 

    recursion_test "yellow" 

    echo "Local variable changed by nested call: $local_var" 
} 

輸出:

Local variable before nested call: red 
Local variable before nested call: yellow 
Local variable changed by nested call: yellow 

在其它的編程語言,比如Java每個方法調用具有其上局部變量保存一個單獨的私人堆棧幀。因此,方法的嵌套調用不能修改父調用中的變量。

在Bash中,所有的調用都共享相同的堆棧框架嗎?有沒有辦法讓不同的調用有單獨的局部變量?如果沒有,是否有一個解決方法來正確編寫遞歸函數,以便一個調用不會影響另一個?

回答

5

你想要內建local。在你的例子中嘗試local local_var=$1

注意:您仍然必須小心,因爲local不是完全私密的,如在C堆棧變量中。這更像是javascriptvar這意味着任何被稱爲[子]功能可以得到它[vs. js的let,其中完全私人]。

下面是一個例子:

recursion_test() { 
    local local_var=$1 
    echo "Local variable before nested call: $local_var" 

    # NOTE: if we use other_func_naughty instead, we get infinite recursion 
    other_func_nice 

    if [[ $local_var == "yellow" ]]; then 
     return 
    fi 

    recursion_test "yellow" 

    echo "Local variable changed by nested call: $local_var" 
} 

other_func_naughty() { 
    local_var="blue" 
} 

other_func_nice() { 
    local local_var="blue" 
} 

recursion_test red 

所以,如果你使用local <whatever>,只是一定要保持一致(即所有函數聲明同樣的方式)