Ik leer shell-scripts door middel van een aantal online tutorials en ik kwam bij het volgende script dat de verschillen tussen globale en lokale variabelen aangeeft.
#!/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
En de output is:
Vóór functieaanroep: var1 is global 1 : var2 is globaal 2
Binnenfunctie: var1 is lokaal 1 : var2 is global 2
Na functieaanroep: var1 is global 1 : var2 is opnieuw gewijzigd
Mijn vraag …
Waarom staat var1
na de functieaanroep " global 1 " in plaats van " opnieuw gewijzigd "? Kan iemand uitleggen?
Answer
var1
wordt lokaal verklaard in de functie. Dus tijdens het uitvoeren van de functie zijn er twee variabelen genaamd var1
: de globale en de lokale; maar de functie kan alleen de lokale “zien” (de lokale “schaduwt” de globale). Dus binnen de functie wordt alles wat je doet met var1
gedaan met de lokale variabele; de globale var1
wordt helemaal niet aangeraakt.
Antwoord
Een manier om denk eraan om je voor te stellen dat de local var1="local 1"
het effect heeft dat de huidige waarde van var1
wordt opgeslagen, met de belofte dat aan het einde van de functie zal worden hersteld, en dan ingesteld op "local 1"
. Met dit mentale model kun je alle variabelen als globaal beschouwen, en variabelen die aan het einde van functies worden hersteld.
Het voorbeeld zou beter zijn geweest als in plaats van echo aan te roepen zowel binnen als buiten de functie had riep een andere functie op die var
had uitgevoerd.
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"
Hier kun je zien in de aanroep naar bar van binnenuit dat foo de waarde oppikt van v1 die is vastgesteld door foo.
Een zoekopdracht op internet naar dynamic scope
vs lexical scope
kan helpen.
Opmerkingen
- " Aan het einde van de functie wordt het hersteld ", dit maakt me duidelijk! Bedankt
Antwoord
In Bash moeten lokale variabelen expliciet worden aangeroepen, anders worden ze als globaal behandeld . Zelfs binnen functies (dat is waar het bereik van toepassing is).
En welk bereik het laatst is ingesteld op een variabele – ofwel lokaal, via een expliciete verklaring van het woord local
, of globaal via weglating – zal zijn wat wordt geretourneerd op het moment dat het wordt aangeroepen via echo
.
Dus, in uw voorbeeld, nadat de functie is aangeroepen, wordt de lokale scope ingesteld op var1
, dus eventuele wijzigingen aan deze variabele blijven niet bestaan buiten de functie. Maar global blijft ingesteld op var2
, dus wijzigingen aan deze variabele doen dit.