Go Langage Cheat Sheet
Go (également connu sous le nom de Golang) est un langage compilé, statiquement typé, développé par Robert Griesemer, Rob Pike et Ken Thompson chez Google. La syntaxe de Go est proche de celle du C, mais il propose : la sécurité mémoire, le GC (Garbage Collection), le typage structurel et la concurrence de style CSP.
Hello world
package main
import "fmt"
func main() {
message := greetMe("world")
fmt.Println(message)
}
func greetMe(name string) (string) {
return "Hello, " + name + "!"
}
$ go buildVariables
Déclaration de variable
var msg string
msg = "Hello"Sténographie
msg := "Hello"Constantes
const Phi = 1.618Les constantes peuvent être des caractères, des chaînes de caractères, des booléens ou des valeurs numériques.
Types de base
Chaînes de caractères (Strings)
str := "Hello"
str := `Multiligne
string`Le type pour les chaînes est string.
Nombres
Types typiques
num := 3 // int
num := 3. // float64
num := 3 + 4i // complex128
num := byte('a') // byte (alias pour uint8)Autres types
var u uint = 7 // uint (non signé)
var p float32 = 22.7 // float 32 bitsPointeurs
func main () {
b := *getPointer()
fmt.Println("La valeur est", b)
}
func getPointer () (myPointer *int) {
a := 234
return &a
}Les pointeurs pointent vers un emplacement mémoire d’une variable. Go est entièrement géré par un ramasse-miettes (garbage collector).
Tableaux (Arrays)
// var numbers [5]int
numbers := [...]int{0, 0, 0, 0, 0}La taille des tableaux est fixe.
Slices (Tranches)
slice := []int{2, 3, 4}
slice := []byte("Hello")Contrairement aux tableaux, les slices ont une taille dynamique.
Contrôle de flux
Conditionnels
if day == "sunday" || day == "saturday" {
rest()
} else if day == "monday" && isTired() {
groan()
} else {
work()
}Déclaration dans if
if _, err := getResult(); err != nil {
fmt.Println("Uh oh")
}Une instruction if peut exécuter une instruction simple avant l’expression conditionnelle.
Switch
switch day {
case "sunday":
// les cas n'ont pas de "fallthrough" par défaut !
fallthrough
case "saturday":
rest()
default:
work()
}Fonctions
Lambdas
myfunc := func() bool {
return x > 10000
}Les fonctions sont des objets de première classe.
Types de retour multiples
a, b := getMessage()
func getMessage() (a string, b string) {
return "Hello", "World"
}Valeurs de retour nommées
func split(sum int) (x, y int) {
x := sum * 4 / 9
y := sum - x
return
}En nommant les valeurs de retour dans la déclaration, return (sans arguments) renverra les variables portant ces noms.
Paquets (Packages)
Chargement
import "fmt"
import "math/rand"
import (
"fmt" // donne fmt.Println
"math/rand" // donne rand.Intn
)Les deux sont identiques.
Alias
import r "math/rand"
r.Intn()Noms exportés
func Hello () {
···
}Les noms exportés commencent par une lettre majuscule.
Paquets
package helloChaque fichier de paquet doit commencer par une déclaration package.
Concurrence
Goroutines
func main() {
// Un "canal" (channel)
ch := make(chan string)
// Démarrer des routines concurrentes
go push("Moe", ch)
go push("Larry", ch)
go push("Curly", ch)
// Lire 3 résultats
// (Puisque nos goroutines sont concurrentes,
// l'ordre n'est pas garanti !)
fmt.Println(<-ch, <-ch, <-ch)
}
func push(name string, ch chan string) {
msg := "Hey, " + name
ch <- msg
}Les canaux sont des objets de communication sécurisés pour la concurrence utilisés dans les goroutines.
Canaux tamponnés (Buffered Channels)
ch := make(chan int, 2)
ch <- 1
ch <- 2
ch <- 3
// erreur fatale :
// all goroutines are asleep - deadlock!Les canaux tamponnés limitent le nombre de messages qu’ils peuvent contenir.
Fermer les canaux
Ferme un canal
ch <- 1
ch <- 2
ch <- 3
close(ch)Parcourir un canal jusqu’à sa fermeture
for i := range ch {
···
}Fermé si ok == false
v, ok := <- chDefer & Panic
Defer
func main() {
defer fmt.Println("Fait")
fmt.Println("Travail en cours...")
}Retarde l’exécution d’une fonction jusqu’à ce que la fonction environnante se termine. Les arguments sont évalués immédiatement, mais l’appel de la fonction n’est exécuté qu’à la fin.
Defer avec Lambdas
func main() {
defer func() {
fmt.Println("Fait")
}()
fmt.Println("Travail en cours...")
}Les lambdas sont préférables pour les blocs différés.
Structs (Structures)
Définition
type Vertex struct {
X int
Y int
}
func main() {
v := Vertex{1, 2}
v.X = 4
fmt.Println(v.X, v.Y)
}Littéraux
v := Vertex{X: 1, Y: 2}
// Les noms de champs peuvent être omis
v := Vertex{1, 2}
// Y est implicite
v := Vertex{X: 1}Vous pouvez également spécifier les noms de champs.
Pointeurs vers des structures
v := &Vertex{1, 2}
v.X = 2Quand v est un pointeur, v.X et (*v).X sont identiques.
Méthodes
Receveurs (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()Il n’y a pas de classes, mais vous pouvez définir des fonctions sur les types en utilisant des receveurs.
Receveurs de pointeur
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` est mis à jour