Basi
Hello World
package main import "fmt" func main() { fmt.Println("Hello, World!") }
Esecuzione e Build
go run main.go # compila ed esegui go build -o app . # compila in binario go test ./... # esegui tutti i test
Inizializzazione Modulo
go mod init github.com/user/project go mod tidy # sincronizza dipendenze
Variabili e Tipi
Dichiarazione
var name string = "Go" age := 15 // dichiarazione breve var x, y int = 1, 2 const Pi = 3.14159
Tipi Base
booltrue, false
stringSequenza di byte UTF-8 immutabile
int, int8..int64Interi con segno (piattaforma / larghezza fissa)
uint, uint8..uint64Interi senza segno
float32, float64Virgola mobile IEEE-754
byteAlias per uint8
runeAlias per int32 (code point Unicode)
Valori Zero
int, float0
boolfalse
string"" (stringa vuota)
pointer, slice, mapnil
Funzioni
Funzione Base
func add(a, b int) int { return a + b }
Valori di Ritorno Multipli
func divide(a, b float64) (float64, error) { if b == 0 { return 0, errors.New("division by zero") } return a / b, nil }
Variadic e Anonime
func sum(nums ...int) int { total := 0 for _, n := range nums { total += n } return total } double := func(x int) int { return x * 2 }
Defer
func readFile(path string) { f, _ := os.Open(path) defer f.Close() // eseguito al ritorno dalla funzione }
Controllo del Flusso
If / Else
if x > 0 { fmt.Println("positivo") } else if x == 0 { fmt.Println("zero") } else { fmt.Println("negativo") }
Ciclo For
for i := 0; i < 10; i++ { } // classico for x < 100 { x *= 2 } // stile while for { break } // infinito for i, v := range slice { } // range
Switch
switch day { case "Mon", "Tue": fmt.Println("inizio settimana") case "Fri": fmt.Println("TGIF") default: fmt.Println("altro") }
Struct e Metodi
Definizione Struct
type User struct { Name string Email string Age int } u := User{Name: "Alice", Email: "[email protected]", Age: 30}
Metodi
func (u User) Greeting() string { return "Ciao, " + u.Name } func (u *User) SetAge(age int) { u.Age = age // receiver puntatore muta }
Embedding
type Admin struct { User // struct embedded Level string } a := Admin{User: User{Name: "Bob"}, Level: "super"} fmt.Println(a.Name) // campo promosso
Interfacce
Definizione e Implementazione
type Stringer interface { String() string } // implementazione implicita — nessuna parola chiave "implements" func (u User) String() string { return u.Name }
Interfacce Comuni
io.ReaderRead(p []byte) (n int, err error)
io.WriterWrite(p []byte) (n int, err error)
fmt.StringerString() string
errorError() string
Type Assertion
var i interface{} = "hello" s, ok := i.(string) // ok == true switch v := i.(type) { case string: fmt.Println(v) case int: fmt.Println(v * 2) }
Goroutine e Channel
Goroutine
go func() { fmt.Println("esecuzione concorrente") }() time.Sleep(time.Second)
Channel
ch := make(chan int) // non bufferizzato buf := make(chan int, 5) // bufferizzato ch <- 42 // invia val := <-ch // ricevi
Select
select { case msg := <-ch1: fmt.Println(msg) case ch2 <- 42: fmt.Println("inviato") case <-time.After(time.Second): fmt.Println("timeout") }
Pattern
sync.WaitGroupAttende il completamento di più goroutine
sync.MutexLock di esclusione reciproca per stato condiviso
context.ContextCancellazione, scadenze, valori con scope alla richiesta
Gestione Errori
Pattern Base
result, err := doSomething() if err != nil { return fmt.Errorf("failed: %w", err) }
Errori Personalizzati
type NotFoundError struct { ID string } func (e *NotFoundError) Error() string { return "not found: " + e.ID }
Pacchetto errors
errors.New(msg)Crea errore semplice
fmt.Errorf("%w", err)Avvolge l'errore con contesto
errors.Is(err, target)Controlla la catena errori per corrispondenza
errors.As(err, &target)Estrae errore tipizzato dalla catena
Slice e Map
Slice
s := []int{1, 2, 3} s = append(s, 4, 5) sub := s[1:3] // [2, 3] cp := make([]int, len(s)) copy(cp, s)
Map
m := map[string]int{"a": 1, "b": 2} m["c"] = 3 val, ok := m["a"] // ok == true delete(m, "b") for k, v := range m { }
Operazioni Slice
len(s)Numero di elementi
cap(s)Capacità dell'array sottostante
append(s, elems...)Aggiunge elementi, può riallocare
copy(dst, src)Copia elementi tra slice
slices.Sort(s)Ordina la slice (Go 1.21+ pacchetto slices)
Pacchetti e Import
Stili di Import
import "fmt" import ( "os" "strings" "github.com/user/pkg" )
Visibilità
Prima lettera maiuscola = esportato (pubblico). Prima lettera minuscola = non esportato (privato al pacchetto). Nessuna parola chiave come public/private necessaria.
Libreria Standard Comune
fmtI/O formattato (Print, Sprintf, Errorf)
osFunzioni OS (file, env, args)
ioPrimitive I/O (Reader, Writer)
net/httpClient e server HTTP
encoding/jsonCodifica/decodifica JSON
stringsFunzioni di manipolazione stringhe
strconvConversioni stringa ↔ numero
testingFramework test unitari
Generics
Parametri di Tipo
func Map[T, U any](s []T, f func(T) U) []U { r := make([]U, len(s)) for i, v := range s { r[i] = f(v) } return r }
Vincoli
type Number interface { ~int | ~float64 } func Sum[T Number](nums []T) T { var total T for _, n := range nums { total += n } return total }
Testing
Test Base
// file: math_test.go func TestAdd(t *testing.T) { got := Add(2, 3) if got != 5 { t.Errorf("Add(2,3) = %d, want 5", got) } }
Comandi Test
go testEsegui test nel pacchetto corrente
go test ./...Esegui tutti i test ricorsivamente
go test -vOutput verbose
go test -run TestAddEsegui test specifico per nome
go test -bench .Esegui benchmark
go test -coverMostra percentuale di copertura