Jag lär mig shell-skript genom några online-självstudier och jag kom till följande skript som förklarar skillnader mellan globala och lokala variabler.
#!/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
Och utdata är:
Före funktionsanrop: var1 är global 1 : var2 är global 2
Invändig funktion: var1 är lokal 1 : var2 är global 2
Efter funktionsanrop: var1 är global 1 : var2 är ändras igen
Min fråga …
Varför är var1
efter funktionsanropet " global 1 " istället för " ändrades igen "? Kan någon förklara?
Svar
var1
förklaras lokal i funktionen. Så under körningen av funktionen finns två variabler som heter var1
: den globala och den lokala; men funktionen kan bara ”se” den lokala (den lokala ”skuggar” den globala). Så i funktionen görs allt som du gör för att var1
gör den lokala variabeln; det globala var1
berörs inte alls.
Svar
Ett sätt att tänk på det är att föreställa sig att local var1="local 1"
har effekten att spara det aktuella värdet av var1
, med ett löfte att i slutet av funktionen den kommer att återställas och sedan ställa in den till "local 1"
. Med denna mentala modell kan du sedan tänka på alla variabler som globala och variabler som återställs i slutet av funktioner.
Exemplet skulle ha varit bättre om istället för att ringa eko både inuti funktionen och utanför den hade kallade en annan funktion som hade skickat ut var
.
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"
Här kan du se i uppmaningen att stapla inifrån foo plockar upp värdet av v1 som fastställdes av foo.
En webbsökning för dynamic scope
vs lexical scope
kan hjälpa.
Kommentarer
- " I slutet av funktionen kommer den att återställas ", detta gör mig tydlig! Tack
Svar
I Bash måste lokala variabler uttryckligen anropas, annars kommer de att behandlas som globala . Till och med inuti funktionerna (det är där omfattningen gäller).
Och vad som helst omfång senast sattes på en variabel – antingen lokal, via en uttrycklig deklaration av ordet local
, eller global via utelämnande – kommer att returneras vid den tidpunkt det kallas via echo
.
Så, i ditt exempel, efter att funktionen har anropats, ställs lokalt omfång in på var1
, så att ändringar av denna variabel inte kvarstår utanför funktionen. Men global förblir inställd på var2
, så ändringar av denna variabel gör det.