Uczę się skryptów powłoki, korzystając z kilku samouczków online i doszedłem do następującego skryptu który deklaruje różnice zmiennych globalnych i lokalnych.
#!/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
A wynik to:
Przed wywołaniem funkcji: var1 jest global 1 : var2 jest global 2
Funkcja wewnętrzna: var1 to lokalna 1 : var2 to global 2
Po wywołaniu funkcji: var1 to global 1 : var2 is ponownie zmieniony
Moje pytanie …
Dlaczego po var1
wywołanie funkcji " global 1 " zamiast " zostało ponownie zmienione "? Czy ktoś może wyjaśnić?
Odpowiedź
var1
jest zadeklarowana jako lokalna w funkcji. Zatem podczas wykonywania funkcji istnieją dwie zmienne o nazwie var1
: globalna i lokalna; ale funkcja „widzi” tylko lokalną (lokalna „przesłania” globalną). Wewnątrz funkcji wszystko, co robisz, aby var1
, jest wykonywane w zmiennej lokalnej; globalna var1
w ogóle nie jest dotykana.
Odpowiedź
Jeden sposób pomyśl o tym, żeby wyobrazić sobie, że local var1="local 1"
skutkuje zapisaniem bieżącej wartości var1
, z obietnicą, że na końcu funkcja, którą zostanie przywrócona, a następnie ustawienie jej na "local 1"
. Z tym modelem myślowym możesz wtedy myśleć o wszystkich zmiennych jako o zmiennych globalnych, a zmienne są przywracane na końcu funkcji.
Przykład byłby lepszy, gdyby zamiast wywoływania echa zarówno wewnątrz funkcji, jak i poza nią, wywołała inną funkcję, która zwróciła 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"
Tutaj możesz zobaczyć w wywołaniu baru od wewnątrz foo pobiera wartość v1 ustaloną przez foo.
Pomocne może być wyszukiwanie w sieci hasła dynamic scope
w porównaniu z lexical scope
.
Komentarze
- " Pod koniec funkcji zostanie ona przywrócona ", to wyjaśnia mój umysł! Dzięki
Odpowiedź
W Bash zmienne lokalne muszą być jawnie wywoływane, inaczej będą traktowane jako globalne . Nawet wewnątrz funkcji (gdzie obowiązuje zakres).
I niezależnie od tego, jaki zakres był ostatnio ustawiony dla zmiennej – albo lokalny, poprzez jawną deklarację słowa local
lub globalny przez pominięcie – będzie zwracany w momencie wywołania przez echo
.
Tak więc w w Twoim przykładzie, po wywołaniu funkcji lokalny zasięg jest ustawiany na var1
, więc wszelkie zmiany tej zmiennej nie są zachowywane poza funkcją. Ale global pozostaje ustawiony na var2
, więc zmiany tej zmiennej tak.