Développement Web

Les bases de la syntaxe Go : variables, types, fonctions

12 min de lecture
📍 Article principal du parcours : Go (Golang) : le guide complet pour débuter
Ce tutoriel fait partie du parcours « Go de zéro ». Pour la vue d’ensemble, lisez d’abord le guide principal.

Les bases de la syntaxe Go : variables, types, fonctions

Votre projet GareBook compile et affiche son accueil. Maintenant il faut lui donner de la matière : représenter un trajet, calculer le prix selon la distance, décider si une réservation est possible. Tout cela repose sur quatre briques que tout programme utilise sans relâche : les variables, les types, les structures de contrôle (conditions et boucles) et les fonctions. Go les rend remarquablement simples, à condition de comprendre deux ou trois règles qui le distinguent des langages que vous avez peut-être croisés.

À la fin de ce tutoriel, vous saurez modéliser un trajet inter-villes avec les bons types, écrire des fonctions qui calculent et décident, et enchaîner conditions et boucles à la manière idiomatique de Go.

🎯 Ce que vous allez apprendre

  • Déclarer des variables et des constantes, et choisir le bon type de base ;
  • Écrire des fonctions, y compris celles qui renvoient plusieurs valeurs ;
  • Maîtriser les conditions (if, switch) et les boucles (for sous toutes ses formes) ;
  • Appliquer tout ça pour calculer le prix et valider la disponibilité d’un trajet GareBook.

🛠️ Ce que vous allez construire

Un fichier de logique métier qui modélise un trajet par quelques variables, calcule son prix en fonction de la distance et du nombre de passagers, et affiche un récapitulatif lisible. C’est le cerveau de calcul de GareBook, que le prochain tutoriel rangera proprement dans des structures.

Prérequis

  • Avoir terminé le tutoriel d’installation : Go installé, module garebook créé ;
  • Savoir lancer go run . dans le dossier du projet ;
  • Niveau : débutant. Test express : si go run . affiche votre message d’accueil, vous êtes prêt.
  • ⏱️ Temps estimé : ~35 minutes.

Étape 1 — Les variables et les types de base

Une variable est un nom qui pointe vers une valeur. En Go, chaque variable a un type fixé à la compilation, et il y a deux façons de la déclarer. La forme courte avec := laisse Go deviner le type d’après la valeur ; la forme longue avec var permet de préciser le type, notamment quand on déclare sans valeur initiale. Voyons les types qui nous serviront pour un trajet :

package main

import "fmt"

func main() {
	// Forme courte : Go déduit le type
	depart := "Dakar"       // string
	arrivee := "Saint-Louis" // string
	distanceKm := 264        // int
	prixKm := 13.5           // float64
	directe := true          // bool

	// Forme longue : on précise le type
	var places int = 7

	fmt.Println(depart, "→", arrivee)
	fmt.Println("Distance :", distanceKm, "km")
	fmt.Println("Places disponibles :", places)
	fmt.Println("Liaison directe :", directe)
	_ = prixKm // on l'utilisera à l'étape suivante
}

Chaque type a un rôle : string pour le texte, int pour les nombres entiers, float64 pour les décimaux (un prix au kilomètre, par exemple), bool pour vrai/faux. La ligne _ = prixKm mérite une explication : Go refuse de compiler si une variable n’est jamais utilisée, et l’underscore _ est la « poubelle » qui permet d’ignorer temporairement une valeur. On s’en débarrassera dès qu’on utilisera vraiment prixKm.

Si vous avez besoin d’une valeur qui ne change jamais — un taux fixe, un nom de gare — utilisez const au lieu de var. Une constante est figée à la compilation, ce qui documente l’intention et empêche toute modification accidentelle.

Un mot sur l’affichage, puisqu’on l’utilisera partout. La fonction fmt.Printf remplace des « verbes » par vos valeurs : %d pour un entier, %s pour une chaîne, %t pour un booléen, %f pour un décimal (et %.2f pour deux chiffres après la virgule), enfin %v qui affiche n’importe quelle valeur dans son format par défaut. Ce dernier est précieux quand on débogue : fmt.Printf("%v\n", monTrajet) imprime toute la structure d’un coup. Choisir le bon verbe évite des surprises — afficher un float64 avec %d, par exemple, produit un message d’erreur de formatage au lieu du nombre attendu. En cas de doute, %v ne se trompe jamais sur le type.

Point d’étapego run . affiche les informations du trajet Dakar → Saint-Louis. Essayez de changer une valeur, par exemple distanceKm, et relancez : la sortie suit.

Étape 2 — Écrire des fonctions

Empiler du code dans main devient vite illisible. Une fonction isole un calcul, lui donne un nom, et le rend réutilisable. En Go, on déclare une fonction avec func, on indique le type de chaque paramètre, puis le type de ce qu’elle renvoie. Écrivons la fonction qui calcule le prix d’un billet à partir de la distance et du tarif au kilomètre :

// prixBillet calcule le prix d'un trajet en FCFA,
// arrondi à la centaine supérieure.
func prixBillet(distanceKm int, prixKm float64) int {
	brut := float64(distanceKm) * prixKm
	// arrondi à la centaine supérieure
	centaines := int(brut/100) + 1
	return centaines * 100
}

Deux points importants ici. D’abord, la conversion float64(distanceKm) : Go n’additionne ni ne multiplie jamais un int et un float64 sans conversion explicite. Cette rigueur évite des arrondis silencieux. Ensuite, la fonction annonce qu’elle renvoie un int (après la parenthèse des paramètres), et le return doit fournir exactement ce type. Appelons-la depuis main :

prix := prixBillet(264, 13.5)
fmt.Printf("Prix Dakar → Saint-Louis : %d FCFA\n", prix)
// Affiche : Prix Dakar → Saint-Louis : 3600 FCFA

La grande particularité de Go arrive maintenant : une fonction peut renvoyer plusieurs valeurs. C’est ce qui sert à signaler une erreur sans interrompre brutalement le programme. Écrivons une fonction qui tente de réserver des places et renvoie à la fois le nombre de places restantes et une indication de succès :

// reserver tente de retirer n places de placesLibres.
// Renvoie les places restantes et un booléen de succès.
func reserver(placesLibres, n int) (int, bool) {
	if n <= 0 || n > placesLibres {
		return placesLibres, false // réservation refusée
	}
	return placesLibres - n, true
}

L’appelant récupère les deux valeurs d’un coup : restantes, ok := reserver(7, 3). Si ok vaut false, la réservation a échoué et on n’a rien retiré. Ce motif « valeur + indicateur » est partout en Go ; au prochain tutoriel, on le remplacera par le couple (valeur, error), encore plus expressif.

Étape 3 — Conditions : if et switch

Décider, c’est le quotidien d’un programme : un trajet est-il complet ? le passager a-t-il l’âge requis ? Go propose if et switch, sans parenthèses autour de la condition mais avec des accolades obligatoires. Une subtilité agréable : if peut déclarer une variable juste avant de tester, variable qui n’existe que dans le bloc :

placesLibres := 7
demande := 9

if restantes, ok := reserver(placesLibres, demande); ok {
	fmt.Printf("Réservé. Il reste %d places.\n", restantes)
} else {
	fmt.Printf("Refusé : %d places demandées, %d disponibles.\n", demande, placesLibres)
}

La variable ok est testée directement, et restantes n’existe que dans le if/else. Quand les cas se multiplient, switch est plus lisible qu’une cascade de if. En Go, pas besoin de break : chaque cas s’arrête tout seul. Classons un trajet selon sa durée :

func categorie(dureeHeures float64) string {
	switch {
	case dureeHeures < 2:
		return "court"
	case dureeHeures < 5:
		return "moyen"
	default:
		return "long"
	}
}

Ce switch sans expression après le mot-clé teste des conditions booléennes l’une après l’autre, comme une chaîne de if/else if mais en plus net. Le default capte tout ce qui n’a pas été pris avant.

Point d’étape — Vous savez écrire une fonction qui calcule, une qui renvoie deux valeurs, et brancher la suite avec if et switch. Testez categorie(1.5), categorie(3) et categorie(8) : vous devez obtenir court, moyen, long.

Étape 4 — Boucles : le for sous toutes ses formes

Go n’a qu’un seul mot-clé de boucle : for. Mais il prend plusieurs formes qui couvrent tous les besoins. La forme classique avec compteur sert à répéter un nombre connu de fois — par exemple lister les départs de la journée :

for heure := 6; heure <= 18; heure += 4 {
	fmt.Printf("Départ prévu à %dh00\n", heure)
}
// 6h00, 10h00, 14h00, 18h00

Depuis Go 1.22, on peut aussi itérer directement sur un entier, ce qui est plus court quand on veut juste répéter N fois :

// Afficher 3 numéros de quai
for quai := range 3 {
	fmt.Printf("Quai n°%d ouvert\n", quai+1)
}

La forme for ... range parcourt une collection — on l’utilisera massivement au prochain tutoriel sur les slices. Et pour une boucle infinie (un serveur qui tourne en continu, par exemple), on écrit simplement for { ... } avec un break pour sortir. Un seul mot-clé, mais toute la souplesse nécessaire.

Assemblons le tout dans un petit récapitulatif de trajet, qui calcule le prix pour plusieurs tailles de groupe :

distance := 264
prixKm := 13.5
fmt.Printf("Trajet Dakar → Saint-Louis (%d km)\n", distance)

for passagers := 1; passagers <= 4; passagers++ {
	total := prixBillet(distance, prixKm) * passagers
	fmt.Printf("  %d passager(s) : %d FCFA\n", passagers, total)
}

Lancé avec go run ., ce bloc affiche le prix pour 1 à 4 passagers, ligne par ligne. Vous avez là, en miniature, la logique de tarification de GareBook.

Étape 5 — Vérification finale

Rassemblez les fonctions prixBillet, reserver et categorie dans votre main.go, appelez-les depuis main, et lancez go run .. Vous devez voir le prix du trajet, le résultat d’une réservation, et la catégorie de durée s’afficher sans erreur. Si le compilateur proteste, lisez le message : il indique le fichier, la ligne, et souvent la correction. C’est votre relecteur automatique.

🐞 Pièges fréquents

Symptôme / erreur Cause probable Correctif
invalid operation: mismatched types int and float64 Vous mélangez un entier et un décimal dans un calcul Convertissez explicitement : float64(monInt) ou int(monFloat)
declared and not used Une variable est créée mais jamais lue Utilisez-la, supprimez-la, ou affectez-la à _ en attendant
missing return at end of function Un chemin du code ne renvoie pas la valeur promise Assurez-vous que tous les branchements se terminent par un return du bon type
Le switch ne fait pas ce qu’on croit Réflexe d’ajouter break ou d’attendre un « fall-through » comme en C En Go, chaque cas s’arrête seul. Pour enchaîner volontairement, écrivez fallthrough
Affectation = au lieu de déclaration := (ou l’inverse) := crée une variable, = en modifie une existante Utilisez := à la première apparition, = ensuite

🌍 Adaptation au contexte ouest-africain

Pour des montants en francs CFA, le type int est votre ami : les prix de billets sont des nombres entiers, sans centimes, et un entier évite les surprises d’arrondi des flottants. Réservez float64 aux calculs intermédiaires (un tarif au kilomètre, un taux) et reconvertissez en int pour le montant final, comme dans prixBillet. Cette discipline — calcul en flottant, stockage et affichage en entier — vous évitera les classiques « 3599,9999 FCFA » qui font mauvais effet sur une facture.

Pensez aussi à l’int64 si vous manipulez de très grands nombres (un cumul de recettes annuelles, des identifiants), car sur certaines plateformes int fait 32 bits. Pour de l’argent au-delà du milliard, int64 est plus sûr.

✅ Récapitulatif

Vous tenez maintenant les quatre briques de base de Go. Vous savez déclarer des variables avec := et var, choisir entre int, float64, string et bool, et figer une valeur avec const. Vous écrivez des fonctions — y compris celles qui renvoient plusieurs valeurs, le fondement de la gestion d’erreurs à venir. Vous branchez avec if et switch, et vous bouclez avec les différentes formes de for. La logique de tarification de GareBook est en place ; il est temps de structurer ses données.

🧾 Aide-mémoire

Élément Rôle / syntaxe
x := valeur Déclare une variable avec type déduit
var x Type Déclare avec type explicite (valeur zéro par défaut)
const x = valeur Constante figée à la compilation
func f(a int) (int, bool) Fonction renvoyant plusieurs valeurs
float64(x) / int(x) Conversion de type explicite
if init; cond { } Condition avec variable d’initialisation locale
switch { case ...: } Branchement multiple, sans break
for i := 0; i < n; i++ { } Boucle classique à compteur
for i := range n { } Répéter n fois (Go 1.22+)

💪 À vous de jouer

Écrivez une fonction reduction(prix int, passagers int) int qui applique une remise de 10 % à partir de 3 passagers et de 20 % à partir de 5, puis renvoie le prix total réduit. Testez-la pour 2, 3 et 5 passagers.

Voir une solution
func reduction(prix, passagers int) int {
	total := prix * passagers
	switch {
	case passagers >= 5:
		return total * 80 / 100 // -20 %
	case passagers >= 3:
		return total * 90 / 100 // -10 %
	default:
		return total
	}
}

// Dans main :
// fmt.Println(reduction(3600, 2)) → 7200
// fmt.Println(reduction(3600, 3)) → 9720
// fmt.Println(reduction(3600, 5)) → 14400

On calcule la remise en entiers (* 80 / 100) pour rester en FCFA sans flottant. L’ordre des case compte : on teste le seuil le plus haut d’abord.

Tutoriels frères

Pour aller plus loin

FAQ

Pourquoi Go m’oblige-t-il à convertir int en float64 ?
Pour éviter les conversions implicites silencieuses, source classique de bugs d’arrondi. Go préfère que vous décidiez explicitement, ce qui rend le calcul prévisible.

Quand utiliser var plutôt que := ?
Utilisez := par défaut, c’est plus court. Passez à var quand vous déclarez sans valeur initiale (la variable prend alors la « valeur zéro » du type : 0, «  », false) ou quand vous voulez imposer un type précis.

Go a-t-il un opérateur ternaire (cond ? a : b) ?
Non, volontairement. Un simple if/else sur deux lignes fait le travail et reste lisible. C’est dans l’esprit minimaliste du langage.

Que vaut une variable non initialisée ?
Sa « valeur zéro » : 0 pour les nombres, "" pour les chaînes, false pour les booléens, nil pour les pointeurs et les slices. Il n’y a jamais de valeur « indéfinie » aléatoire comme dans certains langages.

Mots-clés : syntaxe Go, variables Go, types Go, fonctions Go, if switch for, valeurs multiples, débuter Golang.

Partager