Menu
Coddy logo textTech

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: 5

Nic 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: 5

Oznacza 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.

 

challenge icon

Wyzwanie

Łatwy

W 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

Poćwicz samodzielnie: Kompilator Go online