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
appendpuò 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
- Che cosa sono i puntatori?
- Puntatori e funzioni
- Receiver per puntatori nei metodi
- new() e quando utilizzare i puntatori