0Pricing
Go Academy · Lezione

Puntatori e funzioni

Passaggio per valore e passaggio tramite puntatore

Puntatori e funzioni è una lezione Go Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Go Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Go Academy include 4 lezioni in totale.

Passaggio per valore

Go passa tutti gli argomenti delle funzioni per valore, creando una copia. Le modifiche all'interno della funzione non influiscono sull'originale:

package main
import "fmt"

func increment(n int) { n++ }

func main() {
    x := 5
    increment(x)
    fmt.Println(x) // 5 — unchanged
}

Passaggio tramite puntatore

Passi un puntatore per consentire alla funzione di modificare l'originale:

package main
import "fmt"

func increment(n *int) { *n++ }

func main() {
    x := 5
    increment(&x)
    fmt.Println(x) // 6
}

Restituzione di puntatori

Le funzioni possono restituire puntatori a valori allocati nell'heap. L'analisi di escape di Go garantisce la sicurezza:

package main
import "fmt"

func newInt(v int) *int { return &v }

func main() {
    p := newInt(42)
    fmt.Println(*p) // 42
}

Efficienza con struct di grandi dimensioni

Passare una struct di grandi dimensioni tramite puntatore evita una copia costosa:

package main
import "fmt"

type BigData struct{ Data [1024]int }

func process(d *BigData) { d.Data[0] = 99 }

func main() {
    bd := BigData{}
    process(&bd)
    fmt.Println(bd.Data[0]) // 99
}

Puntatore a un'interfaccia

È raramente necessario: le interfacce contengono già internamente un puntatore. Passare *interface{} è quasi sempre sbagliato:

package main
import "fmt"

type Stringer interface{ String() string }

func print(s Stringer) { fmt.Println(s.String()) }

// Pass interface directly, NOT *Stringer
type Name string
func (n Name) String() string { return string(n) }

func main() {
    print(Name("Alice"))
}

Parametri opzionali con puntatori

Usi i parametri puntatore per distinguere tra "non fornito" e valore zero:

package main
import "fmt"

func greet(name *string) {
    if name == nil {
        fmt.Println("Hello, stranger")
        return
    }
    fmt.Println("Hello,", *name)
}

func main() {
    s := "Alice"
    greet(&s)
    greet(nil)
}

Modifica tramite slice

Le slice contengono già un puntatore interno, quindi spesso non è necessario usare *[]T. Tuttavia, quando append rialloca, è necessario un puntatore alla slice stessa:

package main
import "fmt"

func addItem(s *[]int, v int) { *s = append(*s, v) }

func main() {
    nums := []int{1, 2, 3}
    addItem(&nums, 4)
    fmt.Println(nums) // [1 2 3 4]
}

Alias tra puntatori

Più puntatori alla stessa variabile creano degli alias: una modifica effettuata tramite un puntatore è visibile tramite tutti gli altri:

package main
import "fmt"

func main() {
    x := 10
    a, b := &x, &x
    *a = 99
    fmt.Println(*b) // 99 — same memory
}

Evitare l'uso eccessivo dei puntatori

Usi i puntatori solo quando è necessario:

  • Per modificare dati all'interno di una funzione
  • Per struct di grandi dimensioni (>= ~64 byte)
  • Per usare nil con il significato di "assente"

Un uso eccessivo dei puntatori aumenta la pressione sul GC e riduce la chiarezza del codice.

Pattern dei puntatori a funzione

Memorizzi i puntatori a funzione in una map per creare tabelle di dispatch:

package main
import "fmt"

func add(a, b int) int { return a + b }
func sub(a, b int) int { return a - b }

func main() {
    ops := map[string]func(int,int)int{
        "+": add, "-": sub,
    }
    fmt.Println(ops["+"](10, 3)) // 13
    fmt.Println(ops["-"](10, 3)) // 7
}

Verifica rapida

Come si consente a una funzione di modificare una variabile intera definita dal chiamante?

Riepilogo

Punti chiave:

  • Go usa il passaggio per valore: usi i puntatori per le modifiche
  • Restituisca puntatori dai costruttori per l'allocazione nell'heap
  • Le slice contengono un puntatore interno, ma append può richiedere *[]T
  • Eviti di usare eccessivamente i puntatori: preferisca i valori per i tipi piccoli

Esercizio

Scriva una funzione normalize che accetti *[]string e converta tutte le stringhe in minuscolo direttamente nella slice usando strings.ToLower.

Domande Frequenti

La lezione «Puntatori e funzioni» è gratuita?

Sì — il testo completo di «Puntatori e funzioni» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Go Academy, passa a CoddyKit PRO. Il corso Go Academy include 4 lezioni in totale.

Cosa imparerò in «Puntatori e funzioni»?

Passaggio per valore e passaggio tramite puntatore Eserciti Go Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Go Academy?

Non è richiesta alcuna esperienza precedente. Go Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «Puntatori e funzioni»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Go Academy?

Sì. Ogni lezione Go Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Che cosa sono i puntatori?
  2. Puntatori e funzioni
  3. Receiver per puntatori nei metodi
  4. new() e quando utilizzare i puntatori
← Torna a Go Academy