Jeg lærer shell-skripting gjennom noen online opplæringsprogrammer, og jeg kom til følgende skript som erklærer forskjeller mellom globale og lokale 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
Og utdataene er:
Før funksjonsanrop: var1 er global 1 : var2 er global 2
Innvendig funksjon: var1 er lokal 1 : var2 er global 2
Etter funksjonsanrop: var1 er global 1 : var2 er endret igjen
Spørsmålet mitt …
Hvorfor er var1
etter funksjonsanropet " global 1 " i stedet for " endret igjen "? Kan noen forklare?
Svar
var1
blir erklært lokal i funksjonen. Så under utførelsen av funksjonen er det to variabler kalt var1
: den globale og den lokale; men funksjonen kan bare «se» den lokale (den lokale «skygger» den globale). Så i funksjonen gjøres alt du gjør for å var1
til den lokale variabelen; det globale var1
blir ikke berørt i det hele tatt.
Svar
En måte å tenk på det er å forestille seg at local var1="local 1"
har den effekten at den lagrer nåverdien til var1
, med et løfte om at på slutten av funksjonen den vil bli gjenopprettet, og deretter sette den til "local 1"
. Med denne mentale modellen kan du da tenke på alle variablene som globale, og variabler som blir gjenopprettet på slutten av funksjonene.
Eksemplet hadde vært bedre hvis i stedet for å ringe ekko både inne i funksjonen og utenfor den hadde kalte en annen funksjon som hadde sendt 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"
Her kan du se i kallet til bar fra innsiden foo plukker opp verdien av v1 som ble etablert av foo.
Et nettsøk etter dynamic scope
vs lexical scope
kan hjelpe.
Kommentarer
- " På slutten av funksjonen blir den gjenopprettet ", dette gjør meg klar! Takk
Svar
I Bash må lokale variabler kalles eksplisitt, ellers vil de bli behandlet som globale . Selv inne i funksjonene (som er der omfanget gjelder).
Og uansett hvilket omfang som sist ble satt på en variabel – enten lokal, via en eksplisitt erklæring om ordet local
, eller global via utelatelse – vil være det som returneres på det tidspunktet det heter via echo
.
Så, i eksempelet ditt, etter at funksjonen er kalt, settes lokalt omfang på var1
, så eventuelle endringer i denne variabelen fortsetter ikke utenfor funksjonen. Men global forblir satt på var2
, så endringer i denne variabelen gjør det.