Menu
Coddy logo textTech

Valore vs riferimento

Lezione 7 di 19 del corso Funzioni e puntatori in Golang di Coddy.

Finora abbiamo imparato a usare i parametri e i valori restituiti dalle funzioni. In questa lezione spiegheremo un altro concetto importante da comprendere quando si lavora con le funzioni.

Consideriamo un programma come questo:

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
}

In questo programma dichiariamo una variabile a, ne stampiamo il valore e poi la passiamo a una funzione chiamata sum. Questa funzione esegue l'addizione 5 + 5. Quale pensi che sarà il risultato di questo codice?

Eseguiamolo e vediamo:

value of a: 5
value of a after addition: 5

Non cambia nulla. C'è un problema: a dovrebbe valere 10 dopo aver chiamato la funzione sum, giusto?

In realtà no, perché in Go, quando passiamo un valore a una funzione, ne viene creata solo una copia e, quando apportiamo modifiche al valore, queste non si riflettono al di fuori della funzione. Il valore cambia solo all'interno della funzione. Possiamo verificarlo stampando il valore all'interno della funzione 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)
}

Se lo eseguiamo, otterremo:

value of a: 5
value inside the function: 10
value of a after addition: 5

Questo significa che il valore cambia all'interno della funzione (ambito della funzione), ma al di fuori della funzione non cambia.

So che hai bisogno di altri dettagli per capirlo. Esaminiamo questo diagramma:

Ora è più chiaro. In questo modo viene creata una nuova variabile con un indirizzo diverso (e questo non va bene nemmeno per la memoria !).

Ecco perché non vediamo le modifiche: le variabili sono diverse😅.

Per risolvere questo problema, possiamo usare un puntatore invece di una copia del valore, in questo modo:

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
}

Ora, invece del valore, passiamo l'indirizzo di memoria sum(&a). Questo significa che la funzione lavorerà con la stessa variabile e non ne creerà una nuova.

 

challenge icon

Sfida

Facile

Nel codice fornito, definiamo una funzione che scambia due valori. Completa il codice affinché la funzione funzioni e produca il risultato desiderato.

Provalo tu

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)
}

Tutte le lezioni di Funzioni e puntatori in Golang

Esercitati da solo: Compilatore Go online