ProgrammationDéveloppeur Go

Expliquez les particularités de la fonction intégrée make dans Go : quand est-elle nécessaire, comment fonctionne l'initialisation et le découpage pour map, slice et channel ? Quelles erreurs sont rencontrées à cause d'une mauvaise utilisation de make et new ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

La fonction make en Go est exclusivement utilisée pour l'initialisation des objets des types : slice, map et channel. Elle alloue la structure de données nécessaire et renvoie un objet prêt à être utilisé (et non un pointeur !).

Exemples :

s := make([]int, 5, 10) // slice de longueur 5, capacité 10 m := make(map[string]int) // map vide ch := make(chan int, 2) // canal avec tampon de 2

Subtilités :

  • Pour slice, les paramètres : longueur (len) et (facultativement) capacité (cap).
  • Pour map et chan — uniquement capacité (taille/buffer initiale) (facultative).
  • La fonction make renvoie déjà un objet initialisé, prêt à être utilisé.
  • Pour les autres types (struct, array), make n'est pas utilisé, ils sont initialisés avec des littéraux ou new (qui renvoie un pointeur sur la valeur nulle).

Comparaison avec new:

  • new(T) renvoie *T, où tous les champs sont nuls.
  • make(T) renvoie T uniquement pour trois types : slice, map, chan.

Question piège

Peut-on obtenir une map fonctionnelle via new au lieu de make ?

m := new(map[string]int) (*m)["a"] = 1 // Que va-t-il se passer ?

Beaucoup pensent que c'est correct, mais cela provoquera un panic à l'exécution : assignment to entry in nil map. Parce que dans la variable *m, il y a nil !

Correct : utiliser make :

m := make(map[string]int) m["a"] = 1 // OK

Exemples d'erreurs réelles dues à l'ignorance des subtilités du sujet


Histoire

Dans un microservice de stockage de cache, une map était créée via var cache map[string]interface{} sans initialisation make, ce qui entraînait un panic lors de l'écriture en production avec des stack traces incompréhensibles. Le problème n'a été identifié qu'après analyse du code : la map était nil.


Histoire

Lors de l'écriture d'un pipeline de données, on avait oublié le tampon du canal et créé via make(chan int). En conséquence, les goroutines se bloquaient, attendant une lecture, alors qu'un échange asynchrone était attendu. L'erreur n'a été remarquée qu'au cours d'un test de montée en charge.


Histoire

Dans un projet où l'initialisation se faisait via new, certains développeurs essayaient d'utiliser new([]int) au lieu de make([]int, 10), obtenant finalement un pointeur sur un slice nil et un panic à l'exécution lors des premières tentatives d'écriture.