全局和局部变量赋值

全局和局部变量赋值

我正在通过一些在线教程学习 shell 脚本,我得到了以下声明全局变量和局部变量差异的脚本。

#!/bin/bash
# Experimenting with variable scope
var_change () {
  local var1='local 1'
  echo Inside function: var1 is $var1 : var2 is $var2
  var1='changed again'
  var2='changed again'
}

var1='global 1'
var2='global 2'

echo Before function call: var1 is $var1 : var2 is $var2

var_change

echo After function call: var1 is $var1 : var2 is $var2

输出是:

在函数调用之前: var1 是全球1: var2 是全球2

内部函数:var1 是本地1: var2 是全球2

函数调用后: var1 是全球1: var2 是又变了

我的问题...

为什么var1在函数调用之后是“global 1”而不是“再次更改”?有人可以解释一下吗?

答案1

var1在函数中被声明为局部的。所以在函数执行过程中有变量命名var1:全局变量和局部变量;但该函数只能“看到”本地函数(本地函数“隐藏”全局函数)。因此,在函数内部,您所做的任何操作var1都是针对局部变量进行的;全局var1根本没有被触及。

答案2

思考它的一种方法是想象 具有local var1="local 1"保存 的当前值的效果var1,并承诺在函数结束时它将恢复它,然后将其设置为"local 1"。有了这个思维模型,您就可以将所有变量视为全局变量,并在函数末尾恢复变量。

var如果不是在函数内部和外部都调用 echo 而是调用另一个输出 的函数,那么这个例子会更好。

bash$ show(){ printf "   The value of %s in %s is '%s'\n" $1 $2 ${!1} ; }
bash$ bar(){ show v1 bar_$1 ; }
bash$ foo(){ show v1 before_foo ; local v1 ; show v1 after_local ; \ 
               v1="changed"; show v1 after_change ; bar via_foo ; }
bash$ v1="global"
bash$ show v1 global_scope
   The value of v1 in global_scope is 'global'
bash$ foo
   The value of v1 in before_foo is 'global'
   The value of v1 in after_local is ''
   The value of v1 in after_change is 'changed'
   The value of v1 in bar_via_foo is 'changed'
bash$ bar direct
   The value of v1 in bar_direct is 'global'
bash$ show v1 global_scope
   The value of v1 in global_scope is 'global'

在这里您可以看到,从 foo 内部对 bar 的调用中获取了由 foo 建立的 v1 的值。

网络搜索dynamic scopevslexical scope可能会有所帮助。

答案3

在 Bash 中,必须显式调用局部变量,否则它们将被视为全局变量。即使在函数内部(这是范围适用的地方)。

并且,无论最后在变量上设置的范围(无论是本地的,通过单词的显式声明local,还是全局的通过省略)都将是在调用 via 时返回的内容echo

因此,在您的示例中,调用函数后,本地范围设置为var1,因此对此变量的任何更改都不会保留在函数外部。但全局保持设置为var2,因此对此变量进行更改。

相关内容