Go è un linguaggio di programmazione compilato e a tipizzazione statica creato in Google. Produce un unico binario nativo, compila in pochi secondi, ha la garbage collection e ha la concorrenza integrata nel linguaggio tramite goroutine e canali. Il suo ambito principale è il software lato server: API, servizi di rete e gli strumenti da riga di comando e per il cloud che li fanno girare.
Ecco un programma Go completo. Premi Run.
Ogni programma Go parte dal package main, in func main(). := dichiara una variabile e ne deduce il tipo (qui []string, uno slice di stringhe). range scorre lo slice e ti restituisce un indice e un valore. fmt e strings vengono dalla libreria standard, che è abbastanza ampia da permettere a molti programmi di non importare nient'altro.
Go o Golang: il nome
Il linguaggio si chiama Go. "Golang" è un soprannome che viene dal primo sito del progetto, golang.org (oggi il sito è go.dev). La gente ha continuato a usarlo perché cercare "go" sul web restituisce di tutto tranne il linguaggio. La documentazione ufficiale dice "Go", ma "golang" è il termine che quasi tutti scrivono in un motore di ricerca, e i due nomi significano la stessa cosa. Non esiste un prodotto o un dialetto "Golang" separato.
Chi ha creato Go e perché
Robert Griesemer, Rob Pike e Ken Thompson hanno iniziato a progettare Go in Google nel 2007. È stato rilasciato come open source nel novembre 2009, e Go 1.0 è uscito nel marzo 2012.
La motivazione era pratica. Le grandi codebase C++ e Java di Google richiedevano molto tempo per la compilazione, i grafi delle dipendenze erano difficili da gestire, e le macchine multicore e i servizi in rete erano la norma, ma scrivere codice concorrente era facile fonte di errori. Il design di Go risponde direttamente a questi problemi:
- Build veloci. Gli import sono espliciti, un import inutilizzato è un errore di compilazione e il compilatore non rianalizza gli header, quindi anche i programmi grandi si compilano in pochi secondi.
- Un linguaggio semplice. Poche parole chiave, un solo ciclo (
for), niente ereditarietà, niente eccezioni. Il codice scritto da persone diverse tende ad assomigliarsi, e questo aiuta le revisioni in un team grande. - La concorrenza come funzionalità del linguaggio. Avviare un'attività concorrente richiede una parola chiave,
go, e i canali permettono alle attività di comunicare. - Distribuzione semplice. Il risultato è un unico binario da copiare su un server. Di solito è collegato staticamente; con cgo attivo, pacchetti come
netpossono collegarsi alla libreria C di sistema, eCGO_ENABLED=0disattiva questo comportamento.
Go 1.0 è arrivato anche con la promessa di compatibilità di Go 1: i programmi scritti per Go 1.0 continuano a compilare e a funzionare con le versioni 1.x successive. In pratica aggiornare la toolchain rompe raramente il tuo codice, ed è uno dei motivi principali per cui i team si fidano di Go per servizi destinati a durare a lungo.
A cosa serve Golang
Go dà il meglio quando un programma comunica in rete, resta in esecuzione a lungo e deve essere facile da distribuire:
| Ambito | Esempi |
|---|---|
| API web e microservizi | servizi HTTP e gRPC, backend per app web e mobili |
| Strumenti per cloud e infrastruttura | Docker, Kubernetes, Terraform, Prometheus |
| Strumenti da riga di comando | CLI per sviluppatori distribuite come un unico binario per piattaforma |
| Networking | proxy, load balancer, server DNS |
| Pipeline di dati | worker che leggono code, trasformano record e scrivono su database |
È meno adatto per app desktop con interfaccia grafica, app mobili, front end per browser e lavoro numerico o di machine learning, dove altri ecosistemi hanno librerie molto migliori.
Caratteristiche principali, con codice
Tipi statici con inferenza
Ogni variabile ha un tipo fissato in fase di compilazione, ma raramente lo scrivi. := lo deduce:
Go non converte mai in silenzio tra tipi numerici. count * price non compila, perché uno è int e l'altro float64; scrivi tu float64(count). Questo esclude troncamenti silenziosi e bug di precisione.
Gli errori sono valori
Go non ha eccezioni. Una funzione che può fallire restituisce un error come ultimo risultato, e il chiamante lo controlla:
Lo schema if err != nil è la riga più riconoscibile del codice Go. È prolisso, ed è proprio questo lo scopo: ogni punto in cui un programma può fallire è visibile là dove succede. Vedi gestione degli errori per incapsulare e ispezionare gli errori.
Goroutine e canali
Una goroutine è una funzione che gira in parallelo con il resto del programma. Costa pochi kilobyte di stack, quindi eseguirne migliaia è normale. I canali passano valori tra le goroutine in modo sicuro:
Le tre goroutine girano in parallelo, quindi le tre righe possono essere stampate in qualsiasi ordine. Eseguilo qualche volta e potresti vedere ordini diversi. main riceve esattamente tre valori, quindi li aspetta tutti prima di terminare.
Interfacce senza "implements"
Un tipo soddisfa un'interfaccia semplicemente avendo i metodi giusti. Non esiste una parola chiave implements:
Rect e Circle non nominano mai Shape, eppure entrambi possono stare in un []Shape. Questo ti permette di definire un'interfaccia nel pacchetto che la usa, anche molto dopo che i tipi concreti sono stati scritti.
Una sola toolchain
Il comando go fa tutto: go run compila ed esegue, go build crea un binario, go test esegue i test, go fmt formatta il codice, go vet individua costrutti sospetti e go mod gestisce le dipendenze. Esiste un solo stile di formattazione ufficiale, imposto da gofmt, quindi nei progetti Go non si discute di parentesi graffe o indentazione.
Cosa Go lascia fuori di proposito
Alcune funzionalità comuni in altri linguaggi mancano di proposito:
- Niente classi né ereditarietà. Usi struct, metodi, interfacce ed embedding.
- Niente eccezioni. Gli errori sono valori restituiti.
panicesiste, ma serve per i bug, non per i fallimenti ordinari. - Niente operatore ternario. Scrivi un
if/else. - Niente parola chiave
while.forcopre tutti i cicli. - Niente overloading delle funzioni né argomenti di default.
- Generics solo da Go 1.18, e volutamente limitati rispetto ai template di C++ o ai generics di Java.
I compromessi, onestamente
Prolissità. I controlli espliciti degli errori e l'assenza di scorciatoie come l'operatore ternario rendono il codice Go più lungo dell'equivalente in Python o Kotlin. Leggerlo è facile; scriverlo richiede più righe.
Garbage collection. Il garbage collector di Go ha pause brevi, ma resta un garbage collector. Per sistemi hard real-time o per codice in cui ogni allocazione conta, C, C++ o Rust ti danno più controllo.
Valori nil. Go ha puntatori, mappe, slice e interfacce nil. Dereferenziare un puntatore nil causa un panic durante l'esecuzione, e il compilatore non lo impedisce come fa il sistema di tipi di Rust.
Un sistema di tipi ridotto. Niente tipi somma, niente enum (li costruisci con costanti e iota) e generics che coprono i casi comuni ma non la programmazione avanzata a livello di tipi.
Lacune nell'ecosistema. Le librerie per servizi web, database e API cloud sono eccellenti. Per interfacce grafiche, calcolo scientifico e machine learning, Python, C++ o Julia offrono molto di più.
Go a confronto con altri linguaggi
| Go | Python | Java | Rust | |
|---|---|---|---|---|
| Tipizzazione | Statica | Dinamica | Statica | Statica |
| Si esegue come | Binario nativo | Interprete | Bytecode JVM | Binario nativo |
| Memoria | Garbage collection | Garbage collection | Garbage collection | Ownership, niente GC |
| Concorrenza | Goroutine, canali | Thread, asyncio (il GIL limita il parallelismo sulla CPU) | Thread, virtual thread | Thread, async |
| Curva di apprendimento | Bassa | Bassa | Media | Alta |
Scegli Go quando vuoi le prestazioni di un linguaggio compilato e una distribuzione semplice, senza la curva di apprendimento di Rust o la verbosità cerimoniale di Java.
Vale la pena imparare Go?
Se scrivi servizi backend, strumenti da riga di comando o qualsiasi cosa nel campo dell'infrastruttura cloud, sì. Go è il linguaggio in cui è scritta gran parte di quell'ecosistema, e leggerne il codice sorgente fa parte del lavoro. Il linguaggio è piccolo, quindi l'investimento è modesto: la sintassi di base richiede qualche giorno, mentre la concorrenza idiomatica e la gestione degli errori richiedono qualche settimana di pratica.
Per iniziare a scrivere Go sul tuo computer, installa Go, poi segui la pagina hello world, che spiega ogni riga di un primo programma.
Domande frequenti
A cosa serve Golang?
Soprattutto a software backend e di infrastruttura: server web e API, microservizi, strumenti da riga di comando, codice di rete e strumenti per il cloud. Docker, Kubernetes, Terraform e Prometheus sono tutti scritti in Go. Si usa raramente per interfacce grafiche desktop, app mobili o data science.
Go e Golang sono la stessa cosa?
Sì. Il nome del linguaggio è Go. "Golang" viene dall'indirizzo del sito originale, golang.org, ed è rimasto perché "go" è una parola difficile da cercare. Entrambi i nomi indicano lo stesso linguaggio e la stessa toolchain.
Chi ha creato il linguaggio di programmazione Go?
Robert Griesemer, Rob Pike e Ken Thompson hanno progettato Go in Google a partire dal 2007. È stato annunciato come open source nel novembre 2009, e Go 1.0, la versione che ha dato inizio alla promessa di compatibilità di Go, è uscito nel marzo 2012.
Go è facile da imparare?
Il linguaggio in sé è piccolo: 25 parole chiave, un solo costrutto di ciclo e una specifica breve che puoi leggere in un pomeriggio. La maggior parte dei programmatori con esperienza in un altro linguaggio scrive Go funzionante in pochi giorni. Le parti che richiedono più tempo sono gli idiomi: la gestione esplicita degli errori, le interfacce e scrivere codice concorrente corretto con goroutine e canali.
Go è compilato o interpretato?
Compilato. go build produce un binario in codice macchina nativo che non dipende da un interprete o da una macchina virtuale. Anche go run compila; si limita a creare il binario in una posizione temporanea e a eseguirlo.