我正在用bash做脚本。在这个网站(http://tldp.org/LDP/abs/html/recurnolocvar.html)中说,即使不使用局部变量,函数也可以递归调用自身。"但没有解释原因。
有一个涉及斐波那契序列的样本函数。他评论了代码,它不需要是本地的,并问为什么,但没有回答。部分如下所示:
Fibonacci ()
{
idx=$1 # Doesn't need to be local. Why not?
if [ "$idx" -lt "$MINIDX" ]
then
echo "$idx" # First two terms are 0 1 ... see above.
else
(( --idx )) # j-1
term1=$( Fibonacci $idx ) # Fibo(j-1)
(( --idx )) # j-2
term2=$( Fibonacci $idx ) # Fibo(j-2)
echo $(( term1 + term2 ))
fi
}
Fibonacci函数有一个" idx"可以通过连续调用修改的变量,因为连续的" idx"定义未声明为本地,因此它应该影响以前的定义。
该网站上的上一个主题(http://tldp.org/LDP/abs/html/localvar.html)表明,如果变量未声明为本地(因此默认为全局),则更改它将反映全局范围的变化。
为什么bash函数可以在不使用局部变量的情况下以递归方式调用自身?
答案 0 :(得分:5)
因为变量实际上是本地的。
进程替换中的命令($()
)由子shell运行。变量值不会从子shell传播回来。因此递归调用不会影响父调用。
在子shell中运行的命令是:
$(command)
)command1 | command2
)(command)
)command&
)>(command)
,<(command)
)没有方法可以从这些传播任何变量值。
答案 1 :(得分:1)
这是因为他通过子shell递归调用函数:
term1=$( Fibonacci $idx ) # Fibo(j-1)
我实际上发现效率低下对于每个级别的递归,一个进程被召唤并可能导致系统过载。最好使用局部变量。