Wartość a referencja
Lekcja 7 z 19 w kursie Funkcje i wskaźniki w Golang w Coddy.
Do tej pory dowiedzieliśmy się, jak używać parametrów i wartości zwracanych przez funkcje. W tej lekcji wyjaśnimy kolejne ważne zagadnienie, które warto zrozumieć podczas pracy z funkcjami.
Rozważmy taki program:
func main() {
a := 5
fmt.Println("value of a:", a)
sum(a)
fmt.Println("value of a after addition:", a)
}
func sum(x int) {
x = x + x
}W tym programie deklarujemy zmienną a, wyświetlamy jej wartość, a następnie przekazujemy ją do funkcji o nazwie sum. Ta funkcja wykonuje dodawanie 5 + 5. Jak myślisz, jaki będzie wynik tego kodu?
Uruchommy go i sprawdźmy:
value of a: 5
value of a after addition: 5Nic się nie zmieniło. Jest tu pewien problem — po wywołaniu funkcji sum wartość a powinna wynosić 10, prawda?
Otóż nie, ponieważ w Go, gdy przekazujemy wartość do funkcji, jest ona tylko kopiowana. Zmiany wprowadzone w tej wartości nie są widoczne poza funkcją. Wartość zmienia się tylko wewnątrz funkcji. Możemy to zobaczyć, jeśli wyświetlimy wartość wewnątrz funkcji sum:
func main() {
a := 5
fmt.Println("value of a:", a)
sum(a)
fmt.Println("value of a after addition:", a)
}
func sum(x int) {
x = x + x
fmt.Println("value inside the function:", x)
}Jeśli uruchomimy ten kod, otrzymamy:
value of a: 5
value inside the function: 10
value of a after addition: 5Oznacza to, że wartość zmienia się wewnątrz funkcji (w zakresie funkcji), ale poza nią pozostaje bez zmian.
Wiem, że potrzebujesz więcej szczegółów, aby to zrozumieć. Przyjrzyjmy się temu diagramowi:
Teraz już rozumiesz. W ten sposób powstaje nowa zmienna z innym adresem (co nie jest dobre również dla pamięci !).
Dlatego nie widzimy zmian — zmienne są różne😅.
Aby rozwiązać ten problem, możemy użyć wskaźnika zamiast kopii wartości, na przykład tak:
func main() {
a := 5
fmt.Println("value of a:", a)
sum(&a)
fmt.Println("value of a after addition:", a)
}
func sum(x *int) {
*x += *x
}Teraz zamiast wartości przekazujemy adres pamięci sum(&a). Oznacza to, że funkcja będzie działać na tej samej zmiennej i nie utworzy nowej.
Wyzwanie
ŁatwyW podanym kodzie definiujemy funkcję, która zamienia miejscami dwie wartości. Uzupełnij kod, aby funkcja działała i uzyskać oczekiwany rezultat.
Spróbuj swoich sił
package main
import "fmt"
func swapValues(a, b int) {
a, b = b, a
}
func main() {
var x, y int = 4,10
fmt.Println("Before swap:")
fmt.Println("x =", x)
fmt.Println("y =", y)
swapValues(x, y)
fmt.Println("After swap:")
fmt.Println("x =", x)
fmt.Println("y =", y)
}
Wszystkie lekcje w sekcji Funkcje i wskaźniki w Golang
1Wprowadzenie
Wprowadzenie4Odtwórz funkcje obsługi ciągów znaków w Go
Ciągi znaków w GolangFunkcja JoinFunkcja ContainsFunkcja IndexWyzwanie podsumowujące nr 1Poćwicz samodzielnie: Kompilator Go online