Scheda di riferimento per Golang
Comandi e costrutti utili in Go
Ecco la struttura di base di un programma Go, i pattern per la gestione degli errori e il confronto tra canali e goroutine.
Foglio di riferimento per Go
Sintassi di base
Dichiarazione del pacchetto
package main
Importazione dei pacchetti
import "fmt"
import (
"fmt"
"math"
)
Funzione principale
func main() {
// Il tuo codice qui
}
Variabili e tipi
Dichiarazione di variabili
var name string
var age int = 25
x := 10 // Dichiarazione breve
Tipi di base
- bool
- string
- int, int8, int16, int32, int64
- uint, uint8, uint16, uint32, uint64
- float32, float64
- complex64, complex128
Strutture di controllo
Istruzione if
if x > 0 {
// codice
} else if x < 0 {
// codice
} else {
// codice
}
Ciclo for
for i := 0; i < 10; i++ {
// codice
}
Ciclo range
for index, value := range collection {
// codice
}
Istruzione switch
switch variable {
case value1:
// codice
case value2:
// codice
default:
// codice
}
Funzioni
Dichiarazione di una funzione
func functionName(param1 type1, param2 type2) returnType {
// codice
return value
}
Valori di ritorno multipli
func divideAndRemainder(x, y int) (int, int) {
return x / y, x % y
}
Strutture dati
Array
var numbers int
numbers := int{1, 2, 3, 4, 5}
Slice
slice := []int{1, 2, 3}
slice := make([]int, 3, 5)
Mappe
m := make(map[string]int)
m["key"] = value
Strutture
type Person struct {
Name string
Age int
}
p := Person{Name: "Alice", Age: 30}
Metodi
Dichiarazione di un metodo
func (r Rectangle) Area() float64 {
return r.width * r.height
}
Interfacce
Dichiarazione di un’interfaccia
type Shape interface {
Area() float64
}
Concorrenza
Goroutine
go functionName()
Canali
ch := make(chan int)
ch <- value // Invio
value := <-ch // Ricezione
Gestione degli errori
Controllo degli errori
if err != nil {
// Gestisci l'errore
}
Defer
defer file.Close()
Test
Funzione di test
func TestFunction(t *testing.T) {
// Codice di test
}
Questo foglio di riferimento copre le costruzioni e i comandi più essenziali del linguaggio Go. Include la sintassi di base, le strutture di controllo, le funzioni, le strutture dati, i metodi, le interfacce, i primitivi di concorrenza e la gestione degli errori. Ricorda che Go enfatizza la semplicità e la leggibilità, quindi queste costruzioni formano la base per scrivere codice Go efficiente e chiaro.
Gestione degli errori in Go
La gestione degli errori in Go è semplice e esplicita, enfatizzando chiarezza e robustezza. Ecco le tecniche principali per gestire gli errori in Go:
- Restituisci gli errori come valori: Le funzioni che possono fallire dovrebbero restituire un errore come ultimo valore di ritorno. Per esempio:
func Hello(name string) (string, error) {
if name == "" {
return "", errors.New("empty name")
}
message := fmt.Sprintf("Hi, %v. Welcome!", name)
return message, nil
}
- Controlla sempre gli errori: Dopo aver chiamato una funzione che restituisce un errore, controlla immediatamente se l’errore non è nil. Per esempio:
result, err := SomeFunction()
if err != nil {
// Gestisci l'errore
log.Fatal(err)
}
- Utilizza l’incapsulamento degli errori: Quando si propagano gli errori lungo la pila di chiamate, incapsulali per aggiungere contesto utilizzando
fmt.Errorf()
con il verbo%w
. Per esempio:
f, err := os.Open(path)
if err != nil {
return nil, fmt.Errorf("open failed: %w", err)
}
-
Utilizza
defer
per la pulizia: Usadefer
per assicurarti che le risorse siano correttamente chiuse o pulite, anche se si verifica un errore. -
Crea tipi di errore personalizzati: Implementa l’interfaccia
error
per i tipi di errore personalizzati per fornire informazioni sull’errore più dettagliate. -
Utilizza il pacchetto
errors
: Sfrutta funzioni comeerrors.New()
per creare messaggi di errore semplici, eerrors.Is()
oerrors.As()
per il controllo e la conversione dei tipi di errore. -
Evita l’uso di
panic
: Riservapanic
per situazioni veramente irrecuperabili. La gestione normale degli errori dovrebbe utilizzare i valori di ritorno. -
Fornisci informazioni sull’errore esplicite: Fai in modo che i messaggi sugli errori siano chiari e informativi per aiutare nel debug e nella risoluzione dei problemi.
Seguendo queste pratiche, puoi creare programmi Go robusti che gestiscono gli errori in modo efficace e mantengono la chiarezza del codice.
Migliori pratiche per Goroutine e Canali in Go
Utilizzo efficiente delle Goroutine
-
Evita la creazione eccessiva di Goroutine: Crea Goroutine con giudizio, considerando la natura del compito e se trae beneficio dall’esecuzione parallela.
-
Sincronizzazione corretta: Utilizza meccanismi di sincronizzazione come canali o gruppi di attesa per gestire efficacemente le Goroutine e prevenire il consumo di risorse.
-
Considera la natura del compito: Valuta se un compito trae realmente beneficio dall’esecuzione concorrente prima di utilizzare le Goroutine.
Utilizzo efficace dei Canali
-
Scegli il tipo di canale appropriato: Utilizza canali non bufferizzati per la sincronizzazione e canali bufferizzati quando devi decoupling le operazioni di invio e ricezione.
-
Capacità del buffer: Quando si utilizzano canali bufferizzati, considera attentamente la dimensione del buffer per bilanciare prestazioni e utilizzo delle risorse.
-
Chiudi i canali correttamente: Assicurati che i canali siano chiusi quando non verrà più inviato dati per prevenire blocchi e perdite di risorse.
Pattern di concorrenza
-
Modello del pool di lavoratori: Implementa pool di lavoratori utilizzando Goroutine e canali per una distribuzione efficiente delle attività e la raccolta dei risultati.
-
Modello produttore-consumatore: Utilizza Goroutine come produttori e consumatori, con canali che facilitano il flusso di dati tra di essi.
Gestione degli errori e gestione delle risorse
-
Utilizza
defer
per la pulizia: Utilizza le istruzionidefer
per assicurarti una corretta pulizia delle risorse, anche in presenza di errori. -
Gestisci i panici: Implementa
recover()
in Goroutine di lunga durata per prevenire che l’intero programma venga interrotto a causa di un panico in una singola Goroutine.
Comunicazione e sincronizzazione
-
Preferisci i canali rispetto alla memoria condivisa: Utilizza i canali per la comunicazione tra Goroutine per evitare condizioni di competizione e semplificare la sincronizzazione.
-
Utilizza
select
per più canali: Impiega l’istruzioneselect
per gestire contemporaneamente più operazioni sui canali.
Considerazioni sulle prestazioni
-
Limita le operazioni concorrenti: Utilizza semafori o pool di lavoratori per limitare il numero di operazioni concorrenti e prevenire l’esaurimento delle risorse.
-
Evita l’ottimizzazione prematura: Profila il tuo codice per identificare i collo di bottiglia prima di applicare ottimizzazioni concorrenti.
Test e debug
-
Utilizza il rilevatore di race condition: Esegui regolarmente i test con la bandiera
-race
per rilevare le race condition. -
Scrivi test concorrenti: Crea test che esercitino specificamente i percorsi di codice concorrenti per garantire l’affidabilità.
Seguendo queste buone pratiche, puoi sfruttare efficacemente il modello di concorrenza di Go, rendendo i tuoi programmi più efficienti, mantenibili e meno propensi a problemi comuni legati alla concorrenza.
Vedi altri articoli del blog tecnico.
Aggiornamento di golang su linux
- vai e scarica la nuova versione: https://go.dev/doc/install
- rimuovi l’antica:
sudo rm -rf /usr/local/go
- installa la nuova:
cd Downloads
sudo tar -C /usr/local -xzf go1.24.3.linux-amd64.tar.gz
Link utili
- https://go.dev/
- Generazione di PDF in GO - Librerie ed esempi"
- Prestazioni di AWS lambda: JavaScript vs Python vs Golang
- Risolvere l’errore di GORM AutoMigrate su postgresql
- Riinstallare linux
- Bash Cheat Sheet
- Markdown Cheat Sheet
- Decodifica e stampa di un token JWT
- Popolarità dei linguaggi di programmazione e framework
- Spazio Golang
- Alternative a Beautiful Soup per Go