저는 일부 온라인 튜토리얼을 통해 쉘 스크립팅을 배우고 있으며 전역 변수와 로컬 변수의 차이점을 선언하는 다음 스크립트를 얻었습니다.
#!/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
함수 호출 후에 "다시 변경" 대신 "전역 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에 의해 설정된 v1의 값은 foo 내의 bar 호출에서 얻어지는 것을 볼 수 있습니다.
웹 검색이 dynamic scope
도움 lexical scope
이 될 수 있습니다.
답변3
Bash에서는 지역 변수를 명시적으로 호출해야 하며, 그렇지 않으면 전역 변수로 처리됩니다. 범위가 적용되는 함수 내부에서도 가능합니다.
그리고 변수에 최종적으로 설정된 범위(로컬, 단어의 명시적 선언을 통한 로컬 local
또는 생략을 통한 전역)는 via가 호출될 때 반환됩니다 echo
.
따라서 귀하의 예에서는 함수가 호출된 후 로컬 범위가 로 설정되어 var1
이 변수에 대한 모든 변경 사항이 함수 외부에 유지되지 않습니다. 그러나 전역은 으로 설정되어 있으므로 var2
이 변수가 변경됩니다.