Menu
Coddy logo textTech

Passaggio per valore vs per riferimento

Fa parte della sezione Programmazione orientata agli oggetti del percorso GO di Coddy. Lezione 21 di 107.

Go è un linguaggio passaggio per valore. Quando passi una variabile a una funzione, Go crea una copia di quel valore. Questo significa che le modifiche all’interno della funzione non influiscono sulla variabile originale.

func double(n int) {
    n = n * 2
}

func main() {
    x := 10
    double(x)
    fmt.Println(x)  // 10 (invariato)
}

Lo stesso vale per le struct. Passare una struct a una funzione copia tutti i suoi campi, quindi le modifiche apportate all'interno della funzione vanno perse.

type Person struct {
    Name string
    Age  int
}

func birthday(p Person) {
    p.Age++
}

func main() {
    alice := Person{Name: "Alice", Age: 30}
    birthday(alice)
    fmt.Println(alice.Age)  // 30 (invariato)
}

Per modificare il valore originale, passa invece un puntatore. Il puntatore stesso viene copiato, ma continua a puntare allo stesso indirizzo di memoria, consentendoti di modificare i dati originali.

func birthday(p *Person) {
    p.Age++
}

func main() {
    alice := Person{Name: "Alice", Age: 30}
    birthday(&alice)
    fmt.Println(alice.Age)  // 31 (modified!)
}

Usa i puntatori quando devi modificare il valore originale o quando passi struct di grandi dimensioni per evitare costose copie. Usa i valori quando vuoi proteggere i dati originali da modifiche involontarie.

challenge icon

Sfida

Facile

Creiamo un sistema di carrello della spesa che dimostri la differenza tra passare le struct per valore o tramite puntatore. Vedrai direttamente che solo i parametri puntatore possono modificare i dati originali.

Organizzerai il codice in due file:

  • cart.go: Definisci una struct CartItem con i campi Name (string), Price (float64) e Quantity (int). Crea due funzioni che tentano di aggiornare la quantità:
    • UpdateQuantityByValue riceve un CartItem (per valore) e una nuova quantità, poi imposta la quantità dell'articolo sul nuovo valore
    • UpdateQuantityByPointer riceve un *CartItem (puntatore) e una nuova quantità, poi imposta la quantità dell'articolo sul nuovo valore
    Crea anche un metodo Total su CartItem che restituisce il prezzo moltiplicato per la quantità.
  • main.go: Leggi i dettagli dell'articolo dall'input, crea un CartItem, poi mostra entrambi i metodi di aggiornamento. Prima prova ad aggiornare con la funzione per valore e mostra il risultato, poi aggiorna con la funzione per puntatore e mostra nuovamente il risultato.

Verranno forniti i seguenti input:

  • Riga 1: Nome dell'articolo
  • Riga 2: Prezzo (float)
  • Riga 3: Quantità iniziale (intero)
  • Riga 4: Nuova quantità da impostare (intero)

Formato dell'output:

Initial: [Name] x[Quantity] = $[Total]
After value update: [Name] x[Quantity] = $[Total]
After pointer update: [Name] x[Quantity] = $[Total]

Ad esempio, dati Laptop, 999.99, 1 e 3, l'output dovrebbe essere:

Initial: Laptop x1 = $999.99
After value update: Laptop x1 = $999.99
After pointer update: Laptop x3 = $2999.97

Nota che la quantità rimane 1 dopo l'aggiornamento per valore (la funzione ha modificato una copia), ma cambia in 3 dopo l'aggiornamento tramite puntatore (la funzione ha modificato l'originale). Formatta i totali con due cifre decimali.

Provalo tu

package main

import (
	"fmt"
)

func main() {
	// Leggi l'input
	var name string
	var price float64
	var initialQty, newQty int

	fmt.Scanln(&name)
	fmt.Scanln(&price)
	fmt.Scanln(&initialQty)
	fmt.Scanln(&newQty)

	// TODO: Crea un CartItem con i valori di input

	// TODO: Stampa lo stato iniziale usando il formato:
	// fmt.Printf("Initial: %s x%d = $%.2f\n", ...)

	// TODO: Prova ad aggiornare la quantità usando UpdateQuantityByValue
	// Poi stampa il risultato (nota che la quantità non cambierà)

	// TODO: Aggiorna la quantità usando UpdateQuantityByPointer
	// Poi stampa il risultato (nota che la quantità cambierà)
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Go online