{}const=>[]async()letfn</>var
Développement

Coupes au microscope : capacité, copie, croissance et pièges dans Go

Nous analysons les tranches dans Go sous le capot : comment elles sont organisées, pourquoi la capacité décide, en quoi les tableaux partagés sont dangereux et comment éviter les bogues cachés.

К

Kodik

Auteur

3 min de lecture

Les tranches en Go sont l'un des outils les plus puissants, mais aussi les plus insidieux du langage. À première vue, ils semblent être simplement des « tableaux dynamiques », mais sous le capot, ils ont suffisamment de nuances cachées pour qu'une seule ligne de code se transforme en un bogue, dont le débogage prendra plusieurs heures. Voyons comment ils fonctionnent réellement.

En quoi consiste la coupe

Une tranche dans Go n'est pas un tableau. C'est un « emballage mince » qui stocke :

  • Pointeur sur le tableau — le lieu réel de stockage des données.

  • Longueur (len) — combien d'éléments sont disponibles en ce moment.

  • Capacité (cap) - combien d'éléments peuvent être contenus sans réaffecter la mémoire.

 s := []int{1, 2, 3, 4}
 fmt.Println(len(s)) // 4
 fmt.Println(cap(s)) // 4
🔥 100 000+ étudiants déjà avec nous

Marre de lire la théorie ?
Il est temps de coder !

Kodik — une appli où tu apprends à coder par la pratique. Mentor IA, leçons interactives, projets réels.

🤖 IA 24/7
🎓 Certificats
💰 Gratuit
🚀 Commencer
Ont rejoint aujourd'hui

Capacité et son rôle

La capacité est une réserve. Lorsque nous faisons append, Go vérifie :

  • Si la capacité est suffisante, les nouveaux éléments sont simplement écrits dans le même tableau.

  • Si la capacité est épuisée, Go crée nouveau tableau de plus grande taille et copie les anciennes données.

 s := make([]int, 2, 4) // len=2, cap=4
 s = append(s, 10, 20)  // il y a encore de la place
 fmt.Println(cap(s))    // 4
 s = append(s, 30)      // cap terminé → nouveau tableau
 fmt.Println(cap(s))    // 8

Copie et pièges

La fonction copy effectue une copie superficielle :

 a := []int{1, 2, 3}
 b := make([]int, len(a))
 copy(b, a)
 b[0] = 99
 fmt.Println(a) // [1 2 3]
 fmt.Println(b) // [99 2 3]

Mais si vous attribuez simplement :

 a := []int{1, 2, 3}
 b := a
 b[0] = 99
 fmt.Println(a) // [99 2 3] ❗

Ici, a et b indiquent le même tableau — une erreur fréquente des débutants.

Grow : comment les tranches grossissent

Go ne garantit pas un algorithme de croissance précis, mais fonctionne généralement comme ceci :

  • Si la capacité est petite, elle double.

  • Si la capacité est déjà grande, elle augmente d'environ 25 %.

👉 Par conséquent, lorsque vous travaillez avec des données volumineuses, il est préférable d'allouer à l'avance make([]T, 0, N) avec la marge nécessaire.

Pièges : où les développeurs se brûlent le plus souvent

  1. Tableau sous-jacent commun

     a := []int{1, 2, 3, 4, 5}
     b := a[:3]
     c := a[2:]
     c[0] = 99
     fmt.Println(b) // [1 2 99] 😱

    b et c utilisent le même tableau.

  2. La croissance brise le « lien »

     a := []int{1, 2, 3}
     b := a
     a = append(a, 4) // cap épuisé → nouveau tableau
     b[0] = 99
     fmt.Println(a) // [1 2 3 4]
     fmt.Println(b) // [99 2 3]

    Après la croissance, a a déjà un autre tableau, et la connexion avec b a été perdue.

  3. Tranches d'un grand massif

     big := make([]byte, 1e6)
     small := big[:1]
     // small semble minuscule, mais garde en mémoire tout le mégaoctet

    Solution : copy dans une nouvelle section.

Total

Les tranches dans Go sont un outil pratique, mais :

  • rappelez-vous de la capacité et de la croissance,

  • utilisez copy si vous voulez des données indépendantes,

  • soyez prudent avec les « coupes de coupes ».

Comprendre la structure des coupes sous le capot vous évitera des bogues inattendus et vous aidera à écrire un code plus fiable.

🎯Arrête de reporter

Tu as aimé l'article ?
Place à la pratique !

Avec Kodik, tu ne lis pas seulement — tu codes immédiatement. Théorie + pratique = vraies compétences.

Pratique instantanée
🧠L'IA explique le code
🏆Certificat

Sans inscription • Sans carte