Introduction à Go
Go (aussi appelé Golang) est un langage de programmation open-source développé par Google en 2009. Go combine la simplicité de Python avec les performances de C/C++, et offre une excellente gestion de la concurrence avec les goroutines.
🚀 Qu'est-ce que Go ?
Go est un langage de programmation compilé, statiquement typé, et concurrent. Go a été conçu pour être simple, efficace et productif, avec une compilation rapide et une exécution performante.
💡 Pourquoi Go est si populaire ?
- Performance - Compilation rapide et exécution performante, proche de C/C++
- Simplicité - Syntaxe claire et minimaliste, facile à apprendre
- Concurrence - Goroutines et channels pour une programmation concurrente facile
- Google - Développé et maintenu par Google, utilisé par de grandes entreprises
- Multiplateforme - Compile vers un seul binaire pour Windows, Linux, macOS
- Écosystème - Bibliothèque standard riche, outils intégrés (go fmt, go test)
🚀 Pourquoi apprendre Go ?
Go est un excellent choix pour le développement backend et les microservices :
- ✅ Backend moderne - Parfait pour créer des APIs REST, microservices, et applications cloud
- ✅ Performance - Applications rapides et efficaces en mémoire
- ✅ Concurrence - Goroutines pour gérer des milliers de connexions simultanées
- ✅ Très demandé - Utilisé par Google, Docker, Kubernetes, Uber, Dropbox
- ✅ Simple - Syntaxe claire, compilation rapide, pas de dépendances complexes
- ✅ Écosystème cloud - Idéal pour le développement cloud-native et DevOps
📋 Prérequis pour apprendre Go
Pour apprendre Go efficacement, il est recommandé d'avoir :
- ✅ Base en programmation - Comprendre les concepts de base (variables, conditions, boucles)
- ✅ Logique - Avoir une bonne compréhension de la logique de programmation
💡 Note importante : Pour compiler du code Go, vous avez besoin du Go SDK. Téléchargez-le depuis go.dev. Vous pouvez utiliser VS Code avec l'extension Go, ou GoLand (IDE JetBrains).
🎯 Cas d'usage de Go
Go est utilisé dans de nombreux domaines :
- Backend & APIs - Développement d'APIs REST, microservices, services backend
- Cloud & DevOps - Docker, Kubernetes, outils cloud-native
- Systèmes distribués - Applications distribuées, systèmes de fichiers
- Outils CLI - Outils en ligne de commande performants
- Networking - Serveurs réseau, proxies, load balancers
📝 Syntaxe de base
La syntaxe Go est simple et claire. Go utilise des accolades {} pour définir les blocs de code et nécessite un point-virgule ; (optionnel, ajouté automatiquement).
# Premier programme Python
print("Bonjour, monde !")
# Variables
nom = "NiangProgrammeur"
age = 25
# F-strings pour formater les chaînes (Python 3.6+)
print(f"Je m'appelle {nom} et j'ai {age} ans")
# Opérations simples
resultat = 10 + 5
print(f"10 + 5 = {resultat}")
💡 Points importants sur la syntaxe Go :
- Go utilise des accolades
{}pour définir les blocs de code - Les commentaires utilisent
//pour une ligne ou/* */pour plusieurs lignes - Point-virgule optionnel - Go ajoute automatiquement les point-virgules
- Chaque fichier Go doit appartenir à un package (package main pour exécutables)
- Fonction main - Point d'entrée :
func main() - Conventions - Utilisez camelCase pour les variables, PascalCase pour les exports
🔍 Exemple de syntaxe détaillée
Voici un exemple complet montrant plusieurs aspects de la syntaxe Go :
# Définition d'une fonction
def calculer_moyenne(nombres):
"""Calcule la moyenne d'une liste de nombres."""
if len(nombres) == 0:
return 0
somme = sum(nombres)
moyenne = somme / len(nombres)
return moyenne
# Utilisation
notes = [15, 18, 12, 20, 16]
moyenne = calculer_moyenne(notes)
print(f"La moyenne est : {moyenne}")
🔤 Variables
En Go, les variables peuvent être déclarées de plusieurs façons. Go est un langage statiquement typé, ce qui signifie que le type doit être connu à la compilation.
# Déclaration de variables
nom = "Python" # String (chaîne de caractères)
age = 30 # Integer (entier)
prix = 19.99 # Float (nombre décimal)
est_actif = True # Boolean (booléen)
valeur_nulle = None # NoneType (valeur nulle)
# Affichage
print(nom)
print(age)
print(prix)
print(est_actif)
print(valeur_nulle)
# Réassignation (changement de type)
variable = 10
print(type(variable)) #
variable = "Dix"
print(type(variable)) #
# Noms de variables valides
nom_utilisateur = "Bassirou"
age_utilisateur = 25
_privé = "variable privée"
CONSTANTE = 3.14159 # Convention pour les constantes
📌 Règles pour les noms de variables :
- Doivent commencer par une lettre ou un underscore
_ - Peuvent contenir des lettres, chiffres et underscores
- Sont sensibles à la casse (
age≠Age) - Ne peuvent pas être des mots-clés Go
- Convention : utilisez
camelCasepour les variables
📊 Types de données
Go a plusieurs types de données intégrés. Voici les principaux :
# Types de base (scalaires)
texte = "Hello" # str (string)
nombre = 42 # int (integer)
decimal = 3.14 # float (floating point)
booleen = True # bool (boolean)
valeur_nulle = None # NoneType
# Collections (structures de données)
liste = [1, 2, 3, 4, 5] # list (liste ordonnée, modifiable)
tuple = (1, 2, 3) # tuple (liste ordonnée, immuable)
dictionnaire = {"nom": "Python", "age": 30} # dict (paires clé-valeur)
ensemble = {1, 2, 3, 4} # set (ensemble unique, non ordonné)
# Vérifier le type
print(type(texte)) #
print(type(nombre)) #
print(type(liste)) #
print(type(dictionnaire)) #
# Conversion de types
age_str = str(25) # Convertir en string
age_int = int("25") # Convertir en entier
prix_float = float("19.99") # Convertir en décimal
📚 Types de données Go :
- string - Chaînes de caractères
- int, int8, int16, int32, int64 - Entiers signés
- uint, uint8, uint16, uint32, uint64 - Entiers non signés
- float32, float64 - Nombres décimaux
- bool - Booléens (true/false)
- byte - Alias pour uint8
- rune - Alias pour int32 (caractère Unicode)
🔢 Opérateurs
Go supporte les opérateurs arithmétiques, de comparaison, logiques et d'assignation :
# Opérateurs arithmétiques
a = 10
b = 3
print(a + b) # Addition: 13
print(a - b) # Soustraction: 7
print(a * b) # Multiplication: 30
print(a / b) # Division: 3.3333333333333335
print(a // b) # Division entière: 3
print(a % b) # Modulo (reste): 1
print(a ** b) # Puissance: 1000
# Opérateurs de comparaison
print(a > b) # True (supérieur à)
print(a < b) # False (inférieur à)
print(a >= b) # True (supérieur ou égal)
print(a <= b) # False (inférieur ou égal)
print(a == b) # False (égalité)
print(a != b) # True (différent)
# Opérateurs logiques
x = True
y = False
print(x and y) # False (ET logique)
print(x or y) # True (OU logique)
print(not x) # False (NON logique)
# Opérateurs d'assignation
c = 5
c += 3 # Équivalent à c = c + 3 (c devient 8)
c -= 2 # Équivalent à c = c - 2 (c devient 6)
c *= 2 # Équivalent à c = c * 2 (c devient 12)
c /= 3 # Équivalent à c = c / 3 (c devient 4.0)
# Opérateurs d'identité
liste1 = [1, 2, 3]
liste2 = [1, 2, 3]
liste3 = liste1
print(liste1 is liste2) # False (objets différents)
print(liste1 is liste3) # True (même objet)
print(liste1 == liste2) # True (valeurs égales)
🔀 Structures conditionnelles
Go utilise if, else if et else pour les conditions. Go supporte aussi switch pour les sélections multiples.
# Structure if simple
age = 20
if age >= 18:
print("Vous êtes majeur")
else:
print("Vous êtes mineur")
# Structure if/elif/else
age = 15
if age >= 18:
print("Vous êtes majeur")
print("Vous pouvez voter")
elif age >= 13:
print("Vous êtes adolescent")
elif age >= 6:
print("Vous êtes enfant")
else:
print("Vous êtes un bébé")
# Conditions multiples
note = 85
if note >= 90:
mention = "Excellent"
elif note >= 80:
mention = "Très bien"
elif note >= 70:
mention = "Bien"
elif note >= 60:
mention = "Assez bien"
else:
mention = "Insuffisant"
print(f"Votre mention : {mention}")
# Opérateur ternaire (expression conditionnelle)
age = 20
statut = "Majeur" if age >= 18 else "Mineur"
print(statut)
# Conditions avec and/or
age = 25
permis = True
if age >= 18 and permis:
print("Vous pouvez conduire")
else:
print("Vous ne pouvez pas conduire")
🔄 Boucles
Go propose une seule boucle : for, qui peut être utilisée de différentes façons (comme while, for classique, range) :
# Boucle for avec range()
for i in range(5):
print(i) # Affiche 0, 1, 2, 3, 4
# range() avec début et fin
for i in range(1, 6):
print(i) # Affiche 1, 2, 3, 4, 5
# range() avec pas
for i in range(0, 10, 2):
print(i) # Affiche 0, 2, 4, 6, 8
# Boucle for avec liste
fruits = ["pomme", "banane", "orange"]
for fruit in fruits:
print(f"J'aime les {fruit}")
# Boucle for avec index (enumerate)
fruits = ["pomme", "banane", "orange"]
for index, fruit in enumerate(fruits):
print(f"{index}: {fruit}")
# Boucle while
compteur = 0
while compteur < 5:
print(compteur)
compteur += 1
# Boucle while avec break
compteur = 0
while True:
print(compteur)
compteur += 1
if compteur >= 5:
break # Sortir de la boucle
# continue (passer à l'itération suivante)
for i in range(10):
if i % 2 == 0: # Si i est pair
continue # Passer au suivant
print(i) # Affiche seulement les impairs: 1, 3, 5, 7, 9
# Boucle for avec else
for i in range(5):
print(i)
else:
print("Boucle terminée") # Exécuté si la boucle se termine normalement
⚙️ Fonctions
Les fonctions en Go sont définies avec func. Go supporte les fonctions avec plusieurs valeurs de retour, ce qui est très utile pour la gestion d'erreurs.
# Fonction simple (sans paramètres)
def dire_bonjour():
print("Bonjour !")
dire_bonjour() # Appel de la fonction
# Fonction avec paramètres
def saluer(nom):
return f"Bonjour, {nom} !"
message = saluer("Python")
print(message) # "Bonjour, Python !"
# Fonction avec plusieurs paramètres
def additionner(a, b):
return a + b
resultat = additionner(5, 3)
print(resultat) # 8
# Fonction avec paramètres par défaut
def saluer_personne(nom, message="Bonjour"):
return f"{message}, {nom} !"
print(saluer_personne("Bassirou")) # "Bonjour, Bassirou !"
print(saluer_personne("Bassirou", "Salut")) # "Salut, Bassirou !"
# Fonction avec arguments nommés
def creer_personne(nom, age, ville="Dakar"):
return f"{nom}, {age} ans, habite à {ville}"
print(creer_personne("Bassirou", 25))
print(creer_personne(age=25, nom="Bassirou", ville="Thiès"))
# Fonction avec *args (arguments variables)
def additionner_nombres(*args):
return sum(args)
print(additionner_nombres(1, 2, 3, 4, 5)) # 15
# Fonction avec **kwargs (arguments nommés variables)
def afficher_info(**kwargs):
for cle, valeur in kwargs.items():
print(f"{cle}: {valeur}")
afficher_info(nom="Bassirou", age=25, ville="Dakar")
# Fonction lambda (fonction anonyme)
carre = lambda x: x ** 2
print(carre(5)) # 25
# Utilisation de lambda avec map()
nombres = [1, 2, 3, 4, 5]
carres = list(map(lambda x: x ** 2, nombres))
print(carres) # [1, 4, 9, 16, 25]
📋 Structs & Interfaces
Les structs permettent de regrouper des données. Les interfaces définissent des contrats que les types doivent respecter.
# ========== LISTES ==========
# Création de listes
nombres = [1, 2, 3, 4, 5]
fruits = ["pomme", "banane", "orange"]
liste_mixte = [1, "deux", 3.0, True]
# Accès aux éléments (index commence à 0)
print(fruits[0]) # "pomme" (premier élément)
print(fruits[-1]) # "orange" (dernier élément)
# Modification
fruits[1] = "mangue" # Remplacer "banane" par "mangue"
# Méthodes des listes
fruits.append("kiwi") # Ajouter à la fin
fruits.insert(1, "ananas") # Insérer à l'index 1
fruits.remove("pomme") # Supprimer un élément
fruits.pop() # Supprimer le dernier élément
fruits.pop(0) # Supprimer l'élément à l'index 0
# Autres méthodes utiles
print(len(fruits)) # Longueur de la liste
print(fruits.count("banane")) # Compter les occurrences
fruits.sort() # Trier la liste
fruits.reverse() # Inverser la liste
# Slicing (tranches)
nombres = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(nombres[2:5]) # [2, 3, 4] (de l'index 2 à 4)
print(nombres[:3]) # [0, 1, 2] (du début à l'index 2)
print(nombres[3:]) # [3, 4, 5, 6, 7, 8, 9] (de l'index 3 à la fin)
print(nombres[::2]) # [0, 2, 4, 6, 8] (tous les 2 éléments)
# ========== DICTIONNAIRES ==========
# Création de dictionnaires
personne = {
"nom": "Bassirou",
"age": 25,
"ville": "Dakar"
}
# Accès aux valeurs
print(personne["nom"]) # "Bassirou"
print(personne.get("age")) # 25 (méthode get() plus sûre)
print(personne.get("email", "Non renseigné")) # Valeur par défaut
# Modification et ajout
personne["age"] = 26 # Modifier
personne["email"] = "bassirou@example.com" # Ajouter
# Méthodes des dictionnaires
print(personne.keys()) # Toutes les clés
print(personne.values()) # Toutes les valeurs
print(personne.items()) # Toutes les paires clé-valeur
# Parcourir un dictionnaire
for cle, valeur in personne.items():
print(f"{cle}: {valeur}")
# Supprimer
del personne["email"] # Supprimer une clé
personne.pop("ville") # Supprimer et retourner la valeur
📦 Packages
Go organise le code en packages. Chaque fichier Go appartient à un package, et vous pouvez importer des packages avec <code>import</code>.
# Importer un module complet
import math
print(math.sqrt(16)) # 4.0 (racine carrée)
print(math.pi) # 3.141592653589793
print(math.cos(0)) # 1.0
# Importer avec un alias
import datetime as dt
maintenant = dt.datetime.now()
print(maintenant)
# Importer des fonctions spécifiques
from math import sqrt, pi
print(sqrt(25)) # 5.0
print(pi) # 3.141592653589793
# Importer tout d'un module (non recommandé)
from math import *
print(sin(0)) # 0.0
# Modules standards utiles
import random
print(random.randint(1, 100)) # Nombre aléatoire entre 1 et 100
import os
print(os.getcwd()) # Répertoire courant
import sys
print(sys.version) # Version de Python
# Créer son propre module
# Créer un fichier mon_module.py avec :
# def ma_fonction():
# return "Hello from module"
#
# Puis l'importer :
# import mon_module
# print(mon_module.ma_fonction())
🏗️ Goroutines & Channels
Go excelle en programmation concurrente avec les goroutines (threads légers) et les channels (canaux de communication).
# Définir une classe
class Personne:
# Constructeur (méthode spéciale __init__)
def __init__(self, nom, age):
self.nom = nom # Attribut d'instance
self.age = age
# Méthode d'instance
def se_presenter(self):
return f"Je m'appelle {self.nom} et j'ai {self.age} ans"
def avoir_ans(self, annees):
self.age += annees
return f"Dans {annees} ans, j'aurai {self.age} ans"
# Créer des objets (instances)
personne1 = Personne("Bassirou", 25)
personne2 = Personne("Aminata", 30)
# Utiliser les méthodes
print(personne1.se_presenter())
print(personne2.se_presenter())
print(personne1.avoir_ans(5))
# Accéder aux attributs
print(personne1.nom)
print(personne1.age)
# Classe avec attributs de classe
class Voiture:
# Attribut de classe (partagé par toutes les instances)
nombre_voitures = 0
def __init__(self, marque, modele):
self.marque = marque
self.modele = modele
Voiture.nombre_voitures += 1
def __str__(self):
return f"{self.marque} {self.modele}"
voiture1 = Voiture("Toyota", "Corolla")
voiture2 = Voiture("Honda", "Civic")
print(f"Nombre de voitures créées : {Voiture.nombre_voitures}")
# Héritage
class Etudiant(Personne):
def __init__(self, nom, age, ecole):
super().__init__(nom, age) # Appeler le constructeur parent
self.ecole = ecole
def etudier(self):
return f"{self.nom} étudie à {self.ecole}"
etudiant = Etudiant("Bassirou", 25, "UCAD")
print(etudiant.se_presenter()) # Méthode héritée
print(etudiant.etudier()) # Méthode spécifique
📁 Manipulation de fichiers
Go permet de lire et écrire dans des fichiers facilement avec le package os et io.
# Écrire dans un fichier (mode 'w' = write)
with open("fichier.txt", "w", encoding="utf-8") as f:
f.write("Bonjour Python !\n")
f.write("Ceci est la deuxième ligne\n")
# Lire un fichier (mode 'r' = read)
with open("fichier.txt", "r", encoding="utf-8") as f:
contenu = f.read()
print(contenu)
# Lire ligne par ligne
with open("fichier.txt", "r", encoding="utf-8") as f:
for ligne in f:
print(ligne.strip()) # strip() enlève les sauts de ligne
# Lire toutes les lignes dans une liste
with open("fichier.txt", "r", encoding="utf-8") as f:
lignes = f.readlines()
print(lignes)
# Ajouter à un fichier (mode 'a' = append)
with open("fichier.txt", "a", encoding="utf-8") as f:
f.write("Nouvelle ligne ajoutée\n")
# Modes de fichier
# 'r' - Lecture (défaut)
# 'w' - Écriture (écrase le fichier existant)
# 'a' - Ajout (ajoute à la fin)
# 'x' - Création exclusive (erreur si existe)
# 'b' - Mode binaire (rb, wb)
# 't' - Mode texte (défaut, rt, wt)
# '+' - Lecture et écriture (r+, w+, a+)
# Gestion d'erreurs
try:
with open("fichier_inexistant.txt", "r") as f:
contenu = f.read()
except FileNotFoundError:
print("Le fichier n'existe pas")
except PermissionError:
print("Permission refusée")
except Exception as e:
print(f"Erreur : {e}")
💡 Bonne pratique : Utilisez defer pour fermer les fichiers automatiquement. Cela garantit que le fichier sera fermé même en cas d'erreur.
🎓 Prochaines étapes
Félicitations ! Vous avez maintenant une solide base en Go.
✅ Ce que vous avez appris :
- Syntaxe Go et variables
- Types de données (string, int, float, bool)
- Opérateurs et expressions
- Structures conditionnelles (if, else, switch)
- Boucles (for)
- Fonctions et valeurs de retour multiples
- Structs et interfaces
- Packages et imports
- Goroutines et channels
- Manipulation de fichiers
🚀 Pour aller plus loin :
- Concurrence avancée - Goroutines, channels, select
- Interfaces - Polymorphisme en Go
- Packages - Créer et utiliser des packages
- Développement web - net/http pour créer des serveurs HTTP
- Bases de données - database/sql pour interagir avec les BDD