Sommaire
- Introduction à Go
- Qu’est-ce que Go ?
- Historique et philosophie
- Installation et configuration
- Espace de travail Go (GOPATH, Modules)
- Bases du Langage
- Syntaxe de base
- Variables et types de données
- Constantes
- Opérateurs
- Structures de contrôle (if, for, switch)
- Fonctions
- Pointeurs
- Types Composés
- Tableaux (Arrays)
- Slices
- Maps
- Structs
- Interfaces
- Déclaration et implémentation
- Interfaces vides
- Gestion des Erreurs
- Le type
error
- Gestion des erreurs avec
if err != nil
- Panic et Recover
- Le type
- Concurrence (Goroutines et Channels)
- Goroutines
- Channels (synchronisés et bufferisés)
- Le mot-clé
select
- Mutexes et WaitGroups
- Packages et Modules
- Création et utilisation de packages
- Gestion des dépendances avec Go Modules
- Entrées/Sorties (I/O)
- Le package
io
- Lecture et écriture de fichiers
- Manipulation de chaînes de caractères
- Le package
- Tests en Go
- Le package
testing
- Tests unitaires
- Tests d’exemple
- Le package
- Développement Web avec Go
- Le package
net/http
- Création de serveurs web
- Gestion des requêtes et réponses
- Frameworks populaires (Gin, Echo)
- Le package
- Bonnes Pratiques
- Conventions de nommage
- Formatage du code (go fmt)
- Documentation (go doc)
- Ressources et Communauté
- Documentation officielle
- Communautés en ligne
1. Introduction à Go
Qu’est-ce que Go ?
Go (ou Golang) est un langage de programmation compilé, concurrent et typé statiquement, développé par Google. Il a été conçu pour être simple, efficace et fiable.
Historique et philosophie
- Développé chez Google par Robert Griesemer, Rob Pike et Ken Thompson.
- Première version en 2009.
- Objectifs : simplicité, concurrence, performance.
- Inspiré par des langages comme C, Pascal et Newsqueak.
Installation et configuration
- Télécharger le paquetage d’installation depuis le site officiel.
- Installer Go en suivant les instructions spécifiques à votre système d’exploitation.
- Configurer les variables d’environnement (GOPATH, PATH).
Espace de travail Go (GOPATH, Modules)
- GOPATH (déprécié) : Ancien système de gestion des dépendances. Définit l’emplacement du code source Go.
- Go Modules (recommandé) : Nouveau système de gestion des dépendances. Permet de gérer les dépendances de manière plus flexible et isolée.
# Activer les modules Go
go env -w GO111MODULE=on
# Initialiser un module Go
go mod init nom_du_module
2. Bases du Langage
Syntaxe de base
- Similaire à C, mais avec une syntaxe plus propre et plus simple.
- Utilisation de
:=
pour l’inférence de type lors de la déclaration et de l’initialisation. - Pas de point-virgule obligatoire à la fin des instructions.
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
Variables et types de données
- Déclaration :
var nom_variable type
ounom_variable := valeur
- Types de base :
int
,int8
,int16
,int32
,int64
: Entiers signésuint
,uint8
,uint16
,uint32
,uint64
: Entiers non signésfloat32
,float64
: Nombres à virgule flottantecomplex64
,complex128
: Nombres complexesbool
: Booléens (true ou false)string
: Chaînes de caractères
var age int = 30
name := "John"
var pi float64 = 3.14159
is_valid := true
Constantes
- Déclaration :
const nom_constante type = valeur
- Les constantes doivent être connues à la compilation.
const PI float64 = 3.14159
const MAX_SIZE int = 100
Opérateurs
- Arithmétiques :
+
,-
,*
,/
,%
- Relationnels :
==
,!=
,<
,>
,<=
,>=
- Logiques :
&&
,||
,!
- Affectation :
=
,+=
,-=
,*=
,/=
,%=
- Incrémentation/Décrémentation :
++
,--
x := 10
y := 5
sum := x + y
is_equal := (x == y)
condition := (x > 0 && y < 10)
x++
Structures de contrôle (if, for, switch)
if
: Conditionnellefor
: Boucleswitch
: Sélection multiple
score := 85
if score > 90 {
// ...
} else if score > 80 {
// ...
} else {
// ...
}
for i := 0; i < 5; i++ {
// ...
}
switch score {
case 100:
// ...
case 90:
// ...
default:
// ...
}
Fonctions
- Déclaration :
func nom_fonction(paramètres) type_retour { // corps }
- Possibilité de retourner plusieurs valeurs.
func add(a int, b int) int {
return a + b
}
func divide(a int, b int) (int, error) {
if b == 0 {
return 0, fmt.Errorf("division par zéro")
}
return a / b, nil
}
func main() {
result := add(5, 3)
fmt.Println(result)
}
Pointeurs
- Similaires à C, mais avec une gestion de la mémoire plus sûre.
- Opérateur d’adresse :
&
- Opérateur de déréférencement :
*
var x int = 10
var ptr *int = &x
fmt.Println("Adresse de x:", &x)
fmt.Println("Valeur de ptr:", ptr)
fmt.Println("Valeur pointée par ptr:", *ptr)
*ptr = 20
fmt.Println("Nouvelle valeur de x:", x)
3. Types Composés
Tableaux (Arrays)
- Collection d’éléments du même type avec une taille fixe.
- Déclaration :
var nom_tableau [taille]type
var numbers [5]int
numbers[0] = 10
numbers[1] = 20
names := [3]string{"Alice", "Bob", "Charlie"}
Slices
- Abstraction au-dessus des tableaux, permettant une taille dynamique.
- Déclaration :
var nom_slice []type
- Utilisation de
make
pour créer un slice. - Fonctions
append
etlen
pour manipuler les slices.
var numbers []int
numbers = make([]int, 5) // Crée un slice de taille 5
numbers = append(numbers, 10) // Ajoute un élément
fmt.Println("Taille du slice:", len(numbers))
Maps
- Table de hachage (dictionnaire) associant des clés à des valeurs.
- Déclaration :
var nom_map map[type_clé]type_valeur
- Utilisation de
make
pour créer une map.
var ages map[string]int
ages = make(map[string]int)
ages["Alice"] = 30
ages["Bob"] = 25
fmt.Println("Age de Alice:", ages["Alice"])
Structs
- Type composite regroupant des champs de types différents.
- Déclaration :
type Person struct {
Name string
Age int
}
var person Person
person.Name = "John"
person.Age = 30
fmt.Println("Nom:", person.Name)
4. Interfaces
Déclaration et implémentation
- Une interface définit un ensemble de méthodes qu’un type doit implémenter.
- Un type implémente une interface en définissant toutes les méthodes de l’interface.
type Animal interface {
Speak() string
}
type Dog struct {
Name string
}
func (d Dog) Speak() string {
return "Woof!"
}
var animal Animal = Dog{Name: "Fido"}
fmt.Println(animal.Speak())
Interfaces vides
- L’interface vide
interface{}
peut contenir n’importe quel type de valeur. - Utile pour écrire du code générique.
var i interface{}
i = 10
i = "Hello"
fmt.Println(i)
5. Gestion des Erreurs
Le type error
- Go n’a pas d’exceptions. Les erreurs sont gérées en retournant une valeur de type
error
. - Le type
error
est une interface avec une seule méthode :Error() string
.
Gestion des erreurs avec if err != nil
- La manière la plus courante de gérer les erreurs en Go est de vérifier si la valeur de retour
error
estnil
.
result, err := divide(10, 2)
if err != nil {
fmt.Println("Erreur:", err)
return
}
fmt.Println("Résultat:", result)
Panic et Recover
panic
: Provoque l’arrêt brutal du programme. À utiliser en cas d’erreurs irrécupérables.recover
: Permet de récupérer après unpanic
. Doit être utilisé dans une fonctiondefer
.
func main() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Récupération après panic:", r)
}
}()
// ... code qui peut provoquer un panic ...
}
6. Concurrence (Goroutines et Channels)
Goroutines
- Fonctions légères exécutées de manière concurrente.
- Lancées avec le mot-clé
go
.
go maFonction()
Channels (synchronisés et bufferisés)
- Permettent la communication et la synchronisation entre les goroutines.
- Déclaration :
make(chan type)
- Synchronisés : Bloquent l’expéditeur jusqu’à ce que le récepteur reçoive la valeur.
- Bufferisés : Peuvent stocker un nombre limité de valeurs avant de bloquer l’expéditeur.
ch := make(chan int) // Channel synchronisé
go func() {
ch <- 10 // Envoie la valeur 10 dans le channel
}()
value := <-ch // Reçoit la valeur du channel
fmt.Println(value)
Le mot-clé select
- Permet d’attendre sur plusieurs opérations de channel.
select {
case value := <-ch1:
// ...
case value := <-ch2:
// ...
default:
// ...
}
Mutexes et WaitGroups
Mutex
: Permet de protéger l’accès concurrent à une ressource partagée.WaitGroup
: Permet d’attendre la fin de plusieurs goroutines.
var mutex sync.Mutex
mutex.Lock()
// ... accéder à la ressource partagée ...
mutex.Unlock()
var wg sync.WaitGroup
wg.Add(2) // Ajoute 2 goroutines à attendre
go func() {
defer wg.Done() // Indique que la goroutine est terminée
// ...
}()
go func() {
defer wg.Done()
// ...
}()
wg.Wait() // Attend que toutes les goroutines soient terminées
7. Packages et Modules
Création et utilisation de packages
- Un package est un ensemble de fichiers Go regroupés dans un même répertoire.
- Le nom du package est spécifié en haut de chaque fichier avec le mot-clé
package
. - Les fonctions et les variables exportées (commençant par une majuscule) peuvent être utilisées depuis d’autres packages.
// mypackage/mypackage.go
package mypackage
func MyFunction() {
// ...
}
// main.go
package main
import "mypackage"
func main() {
mypackage.MyFunction()
}
Gestion des dépendances avec Go Modules
- Go Modules est le système de gestion des dépendances intégré à Go.
- Permet de gérer les versions des dépendances et d’assurer la reproductibilité des builds.
go mod init nom_du_module
go get github.com/nom/du/paquet
8. Entrées/Sorties (I/O)
Le package io
- Le package
io
fournit des interfaces de base pour les opérations d’entrée/sortie. - Interfaces principales :
Reader
,Writer
.
Lecture et écriture de fichiers
- Utilisation des packages
os
etio/ioutil
pour lire et écrire des fichiers.
package main
import (
"fmt"
"io/ioutil"
"os"
)
func main() {
// Écriture dans un fichier
err := ioutil.WriteFile("myfile.txt", []byte("Hello, file!"), 0644)
if err != nil {
fmt.Println("Erreur lors de l'écriture:", err)
return
}
// Lecture depuis un fichier
data, err := ioutil.ReadFile("myfile.txt")
if err != nil {
fmt.Println("Erreur lors de la lecture:", err)
return
}
fmt.Println("Contenu du fichier:", string(data))
os.Remove("myfile.txt") // Supprime le fichier
}
Manipulation de chaînes de caractères
- Le package
strings
fournit des fonctions pour manipuler les chaînes de caractères.
import "strings"
str := "Hello, World!"
fmt.Println(strings.ToUpper(str)) // HELLO, WORLD!
9. Tests en Go
Le package testing
- Le package
testing
fournit les outils nécessaires pour écrire des tests en Go. - Les fichiers de test doivent avoir le suffixe
_test.go
. - Les fonctions de test doivent commencer par
Test
.
Tests unitaires
- Vérifient le comportement d’une fonction ou d’une méthode.
// mypackage/mypackage.go
package mypackage
func Add(a, b int) int {
return a + b
}
// mypackage/mypackage_test.go
package mypackage
import "testing"
func TestAdd(t *testing.T) {
result := Add(2, 3)
if result != 5 {
t.Errorf("Add(2, 3) = %d; want 5", result)
}
}
Tests d’exemple
- Fournissent des exemples d’utilisation du code.
- Sont compilés et exécutés lors des tests.
func ExampleAdd() {
result := Add(2, 3)
fmt.Println(result)
// Output: 5
}
10. Développement Web avec Go
Le package net/http
- Le package
net/http
fournit les outils nécessaires pour créer des serveurs web en Go.
Création de serveurs web
- Utilisation de la fonction
HandleFunc
pour enregistrer des gestionnaires de requêtes. - Utilisation de la fonction
ListenAndServe
pour démarrer le serveur.
package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!")
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
Gestion des requêtes et réponses
- L’objet
http.Request
contient des informations sur la requête HTTP. - L’objet
http.ResponseWriter
permet d’écrire la réponse HTTP.
Frameworks populaires (Gin, Echo)
Gin
: Framework web léger et performant.Echo
: Autre framework web populaire, mettant l’accent sur la simplicité et la performance.
11. Bonnes Pratiques
Conventions de nommage
- Utiliser des noms clairs et descriptifs.
- Utiliser le camelCase pour les noms de variables et de fonctions.
- Utiliser des noms courts pour les variables locales.
- Utiliser des noms longs pour les variables globales.
Formatage du code (go fmt)
- Utiliser l’outil
go fmt
pour formater automatiquement le code. - Assure une cohérence du style de code dans tout le projet.
go fmt ./...
Documentation (go doc)
- Écrire des commentaires pour documenter le code.
- Utiliser l’outil
go doc
pour générer la documentation.
go doc nom_du_package