ProgrammationDéveloppeur Go

Quelles sont les fonctions intégrées append, len et cap en Go, comment fonctionnent-elles au niveau du langage et quels dangers cachés des slices sont associés à leur utilisation ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

En Go, les fonctions intégrées append, len et cap jouent un rôle clé dans le travail avec les slices.

  • len(slice) retourne le nombre d'éléments dans le slice.
  • cap(slice) retourne la capacité du slice — le nombre maximal d'éléments avant l'allocation de nouvelle mémoire.
  • append(slice, elems ...T), en cas d'insuffisance de capacité, entraîne la création d'un nouveau tableau (et donc d'un nouveau stockage sous-jacent), ce qui peut modifier de manière inattendue la sémantique du passage du slice.

Exemple :

arr := []int{1,2,3} arr2 := append(arr, 4) // arr2 peut être dans le même backing array ou dans un nouveau, selon cap(arr)

Subtilités :

  • Si vous faites un append à un slice qui a été "découpé" d'un autre slice (ou tableau d'origine), un effet secondaire est possible : la modification des données d'origine.
  • Lors du passage de slices aux fonctions, len/cap affectent uniquement la partie "visible".
  • Lors d'un append dépassant la cap, un nouveau tableau est créé, l'ancien reste inchangé.

Question piégeuse

Que se passe-t-il si vous "découpez" un morceau du slice et ajoutez un élément via append ? Cela affectera-t-il le tableau d'origine ?

Réponse : Si la cap le permet, append écrira l’élément "à la fin" du tableau d'origine, et les modifications sont visibles dans tous les slices qui pointent vers le même tableau.

Exemple :

a := []int{1,2,3,4} b := a[:2] // [1 2], len=2, cap=4 b = append(b, 10) // a change : a -> [1, 2, 10, 4]

Exemples d'erreurs réelles


Histoire

L'équipe a ajouté des éléments à un slice enfant et, de manière inattendue, les données du tableau parent ont changé — cela a provoqué un désaccord dans la logique métier et des bugs difficiles à déboguer dans la répartition des tâches entre les utilisateurs.


Histoire

Lors d'un nouvel appel à append sur un grand slice, on s'attendait à ce qu'un nouveau tableau soit toujours alloué, mais en réalité, plusieurs parties du système continuaient de travailler avec le même "backing array", provoquant des conditions de concurrence et des corruptions de données.


Histoire

Un développeur a alloué un slice de taille fixe à l'aide de make, mais a fait une erreur et a inversé les arguments : make([]int, cap, len). En conséquence, la logique orientée capacité fonctionnait de manière inattendue sur la longueur, ce qui a provoqué un panic lors du dépassement de s[0:len].