Go Linguaggio Programming Cheat Sheet
Go (noto anche come Golang) è un linguaggio compilato e tipizzato staticamente sviluppato da Robert Griesemer, Rob Pike e Ken Thompson presso Google. La sintassi di Go è simile a quella del C, ma offre: sicurezza della memoria, GC (Garbage Collection), tipizzazione strutturale e concorrenza in stile CSP.
Hello world
package main
import "fmt"
func main() {
message := greetMe("world")
fmt.Println(message)
}
func greetMe(name string) (string) {
return "Hello, " + name + "!"
}
$ go buildVariabili
Dichiarazione delle variabili
var msg string
msg = "Hello"Shorthand (forma abbreviata)
msg := "Hello"Costanti
const Phi = 1.618Le costanti possono essere caratteri, stringhe, valori booleani o numerici.
Tipi di base
Stringhe
str := "Hello"
str := `Multiriga
stringa`Il tipo per le stringhe è string.
Numeri
Tipi tipici
num := 3 // int
num := 3. // float64
num := 3 + 4i // complex128
num := byte('a') // byte (alias per uint8)Altri tipi
var u uint = 7 // uint (senza segno)
var p float32 = 22.7 // float a 32 bitPuntatori
func main () {
b := *getPointer()
fmt.Println("Il valore è", b)
}
func getPointer () (myPointer *int) {
a := 234
return &a
}I puntatori puntano a una posizione di memoria di una variabile. Go è completamente gestito dal Garbage Collector.
Array
// var numbers [5]int
numbers := [...]int{0, 0, 0, 0, 0}Gli array hanno una dimensione fissa.
Slice
slice := []int{2, 3, 4}
slice := []byte("Hello")A differenza degli array, le slice hanno una dimensione dinamica.
Controllo del flusso
Condizionali
if day == "sunday" || day == "saturday" {
rest()
} else if day == "monday" && isTired() {
groan()
} else {
work()
}Istruzione all’interno di if
if _, err := getResult(); err != nil {
fmt.Println("Uh oh")
}Un’istruzione if può eseguire una semplice istruzione prima dell’espressione condizionale.
Switch
switch day {
case "sunday":
// i casi non "cadono" (fall through) per impostazione predefinita!
fallthrough
case "saturday":
rest()
default:
work()
}Funzioni
Lambda
myfunc := func() bool {
return x > 10000
}Le funzioni sono oggetti di “prima classe”.
Molteplici tipi di ritorno
a, b := getMessage()
func getMessage() (a string, b string) {
return "Hello", "World"
}Valori di ritorno con nome
func split(sum int) (x, y int) {
x := sum * 4 / 9
y := sum - x
return
}Nominando i valori di ritorno nella dichiarazione, return (senza argomenti) restituirà le variabili con quei nomi.
Pacchetti (Packages)
Caricamento
import "fmt"
import "math/rand"
import (
"fmt" // fornisce fmt.Println
"math/rand" // fornisce rand.Intn
)Entrambi i modi sono corretti.
Alias
import r "math/rand"
r.Intn()Nomi esportati
func Hello () {
···
}I nomi esportati iniziano con una lettera maiuscola.
Pacchetti
package helloOgni file di un pacchetto deve iniziare con la dichiarazione package.
Concorrenza
Goroutine
func main() {
// Un "channel"
ch := make(chan string)
// Avvia routine concorrenti
go push("Moe", ch)
go push("Larry", ch)
go push("Curly", ch)
// Leggi 3 risultati
// (Poiché le nostre goroutine sono concorrenti,
// l'ordine non è garantito!)
fmt.Println(<-ch, <-ch, <-ch)
}
func push(name string, ch chan string) {
msg := "Hey, " + name
ch <- msg
}I canali sono oggetti di comunicazione sicuri per la concorrenza utilizzati nelle goroutine.
Canali con buffer (Buffered Channels)
ch := make(chan int, 2)
ch <- 1
ch <- 2
ch <- 3
// fatal error:
// all goroutines are asleep - deadlock!I canali con buffer limitano il numero di messaggi che possono contenere.
Chiusura dei canali
Chiude un canale
ch <- 1
ch <- 2
ch <- 3
close(ch)Itera su un canale finché non viene chiuso
for i := range ch {
···
}Chiuso se ok == false
v, ok := <- chDefer & Panic
Defer
func main() {
defer fmt.Println("Fatto")
fmt.Println("Lavorando...")
}Ritarda l’esecuzione di una funzione finché la funzione circostante non ritorna. Gli argomenti vengono valutati immediatamente, ma la chiamata alla funzione non viene eseguita fino alla fine.
Defer con Lambda
func main() {
defer func() {
fmt.Println("Fatto")
}()
fmt.Println("Lavorando...")
}Le lambda sono più indicate per i blocchi defer.
Strutture (Structs)
Definizione
type Vertex struct {
X int
Y int
}
func main() {
v := Vertex{1, 2}
v.X = 4
fmt.Println(v.X, v.Y)
}Letterali
v := Vertex{X: 1, Y: 2}
// I nomi dei campi possono essere omessi
v := Vertex{1, 2}
// Y è implicito
v := Vertex{X: 1}È anche possibile specificare i nomi dei campi.
Puntatori a strutture
v := &Vertex{1, 2}
v.X = 2Quando v è un puntatore, v.X e (*v).X sono equivalenti.
Metodi
Ricevitori (Receivers)
type Vertex struct {
X, Y float64
}
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X * v.X + v.Y * v.Y)
}
v := Vertex{1, 2}
v.Abs()Non esistono classi, ma è possibile definire funzioni sui tipi utilizzando i ricevitori.
Ricevitori di puntatori
func (v *Vertex) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
v := Vertex{6, 12}
v.Scale(0.5)
// `v` viene aggiornato