Communitygithub.com

maîtrise-de-go

Skill pour agents de codage IA : Go idiomatique de qualité production (Go 1.22–1.26). +12–26 points de correction sur Claude et GPT-5, zéro régression dans le domaine.

Qu'est-ce que maîtrise-de-go ?

Ce skill encode la sagesse collective de l'écosystème Go (versions 1.22 à 1.26) pour les agents de codage IA comme Claude, GPT-5 et autres. Il fournit des directives complètes pour écrire du Go idiomatique de qualité production, couvrant tout, des structures de projet et conventions de nommage à la gestion des erreurs, la concurrence et les interfaces. Le skill inclut des dizaines de fichiers de référence détaillés pour les plongées approfondies : modèles avancés, performance, test, sécurité, conception d'API, systèmes distribués, cloud natif, observabilité, etc. En suivant ces principes et conventions, les agents IA peuvent éviter les pièges courants de Go, améliorer la lisibilité du code et augmenter la correction de 12 à 26 points par rapport aux agents non guidés.

Compatible avec✓Claude Code✓Codex CLI✓Cursor
npx skills add mythicalhacker/go-mastery

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Skill de Maîtrise de Go

Écrivez du Go idiomatique de qualité production pour tout usage. Ce skill encode la sagesse collective de l'écosystème Go à partir de Go 1.22+ (2024-2026).

Version de base Go : 1.22 | Fonctionnalités jusqu'à : 1.26 | Mis à jour : février 2026

Avant d'écrire du code Go, intériorisez les principes ci-dessous. Pour des plongées approfondies sur des sujets spécifiques, lisez les fichiers référencés.

Fichiers de Référence — À Lire au Besoin

FichierQuand le lire
references/concurrency.mdGoroutine, canal, primitive de synchronisation, travail parallèle
references/http-and-apis.mdServeurs HTTP, routeurs, middleware, API REST/gRPC, WebSockets
references/database.mdSQL, ORM, pools de connexions, migrations, transactions
references/testing.mdTests unitaires, tests d'intégration, benchmarks, fuzzing
references/errors-and-resilience.mdGestion des erreurs, tentatives, circuit breakers, dégradation gracieuse
references/performance.mdProfilage, réduction d'allocation, réglage GC, benchmarking
references/cli-and-config.mdFrameworks CLI, configuration, gestion d'environnement
references/project-patterns.mdDisposition de projet, DI, systèmes de plugins, génération de code
references/platform-and-build.mdCross-compilation, spécificités Windows, intégration, distribution
references/security.mdAuth, secrets, validation d'entrée, TLS, modèles OWASP
references/modern-go.mdFonctionnalités Go 1.21–1.26, modèles dépréciés, ce que le pré-entraînement se trompe
references/advanced-patterns.mdGénériques, machines d'état, streaming, ordonnancement, intégration IA/LLM
references/advanced-resources.mdRessources externes organisées : internes du compilateur/exécution, assembleur, unsafe, cgo, Raft, opérateurs K8s, Wasm, cryptographie, profilage, livres, conférences, articles académiques
references/observability.mdConfiguration OpenTelemetry, traçage, métriques, journalisation structurée avec corrélation de traces, contrôles de santé, enregistreur de vol, check-list d'instrumentation de production
references/ecosystem-and-tooling.mdListes organisées (awesome-go), comparaisons de frameworks (web, ORM, CLI, DI, config), guides de style, CI/CD, Docker, gestion de release, analyse de vulnérabilités, plateformes d'apprentissage, gouvernance Go
references/internals.mdPlanificateur GMP, ramasse-miettes, modèle mémoire, gestion de pile, allocateur mémoire, pipeline du compilateur, unsafe, réflexion, directives compilateur
references/networking.mdServeurs TCP/UDP, délais net.Conn, pooling de connexions, mTLS, sockets Unix, résolveurs DNS, protocoles binaires personnalisés, gnet
references/mcp-and-agents.mdServeurs MCP (mcp-go, SDK officiel), outils/ressources/invites, frameworks d'agents (ADK, langchaingo, eino), modèles multi-agents, gopls MCP
references/api-design.mdNommage REST, pagination (curseur/décalage), erreurs RFC 9457, limitation de débit, versionnement d'API, codegen OpenAPI (oapi-codegen), rétrocompatibilité, en-têtes de dépréciation
references/cgo-and-interop.mdBases CGo, mappage de types C, gestion mémoire à travers la frontière, règles de passage de pointeurs, callbacks, liaison statique/dynamique, cross-compilation, alternatives pure Go
references/design-patterns.mdModèles GoF en Go (factory, builder, strategy, observer, decorator), composition sur héritage, arbre de décision
references/distributed-systems.mdRaft, modèle outbox, sagas, verrouillage distribué, idempotence, CRDTs, hachage cohérent
references/cloud-native.mdKubernetes client-go, opérateurs controller-runtime, webhooks d'admission, élection de leader, Helm/Kustomize
references/debugging-and-diagnostics.mdDébogueur Delve, traces de pile, indicateurs GODEBUG, workflow de profilage, tableaux symptôme-diagnostic
references/style-synthesis.mdRègles de style fusionnées Google + Uber + communauté, nommage, formatage, organisation du code
references/modules-and-dependencies.mdOpérations go.mod, MVS, espaces de travail, GOPROXY, GOAUTH, vendoring, monorepos multi-modules
references/encoding-and-serialization.mdJSON (v1/v2), Protocol Buffers, MessagePack, CBOR, CSV, YAML, TOML, tableau de décision de format
references/wasm-and-embedded.mdWebAssembly (WASI, navigateur), go:wasmexport, TinyGo, modèles embarqués/IoT
references/migration-guides.mdTraductions Go idiomatiques depuis Python, Java, TypeScript, Rust, C++ — cartes conceptuelles et pièges
references/testing-advanced.mdTests basés sur les propriétés (rapid), tests de contrat (Pact), tests de charge (Vegeta), chaos engineering, synctest avancé
references/supply-chain-security.mdgovulncheck, génération SBOM, framework SLSA, cosign, builds reproductibles, compatibilité GODEBUG
references/ebpf.mdeBPF depuis Go (cilium/ebpf), workflow bpf2go, traçage, mise en réseau, profilage niveau noyau
references/event-driven.mdConsommateurs/producteurs Kafka, RabbitMQ, NATS, framework Watermill, DLQ, modèles exactly-once
references/data-structures-and-caching.mdcontainer/heap, container/list, caches LRU, singleflight, cartes fragmentées, filtres bloom, caches à références faibles, modèles de stratégie de cache (aside/write-through/write-behind)
references/ai-ml-beyond-llm.mdInférence ONNX Runtime, Gonum, clients de bases de données vectorielles, pipelines d'incorporation, service ML depuis Go
references/file-io.mdOpérations fichier, composition io.Reader/Writer, I/O bufferisé, streaming, gestion de chemin, os.Root, abstraction fs.FS, fsnotify

Philosophie Centrale

Go est délibérément simple. Résistez à l'envie d'importer la complexité d'autres écosystèmes.

  1. Clarté avant l'astuce. Le code est lu 10x plus qu'il n'est écrit. L'explicite bat l'implicite — les mainteneurs futurs (y compris vous-même) vous remercieront.
  2. Composition sur héritage. Intégrez des interfaces et des structures ; évitez les hiérarchies profondes. Go n'a pas de classes, et c'est intentionnel — de petites pièces composables battent des arbres de types complexes.
  3. Acceptez des interfaces, retournez des structures. Les fonctions doivent dépendre du comportement (interfaces) et exposer des types concrets. Cela maintient les sites d'appel flexibles tout en rendant les implémentations découvrables et débogables.
  4. Rendez la valeur zéro utile. Concevez les types pour que var x T soit prêt à l'emploi sans initialisation. Cela élimine toute une classe de bugs de pointeur nil et rend les API naturelles (bytes.Buffer, sync.Mutex, http.Client fonctionnent tous à la valeur zéro).
  5. Les erreurs sont des valeurs. Gérez-les ; ne les ignorez jamais. Enveloppez-les avec du contexte en utilisant fmt.Errorf("doing X: %w", err). Les erreurs ignorées deviennent des échecs silencieux qui surgissent des heures plus tard en production.
  6. Ne démarrez pas de goroutines que vous ne pouvez pas arrêter. Chaque goroutine a besoin d'un chemin d'arrêt via l'annulation de contexte ou la fermeture de canal. Les goroutines qui fuient consomment de la mémoire indéfiniment et rendent l'arrêt gracieux impossible.
  7. stdlib d'abord. La bibliothèque standard de Go est inhabituellement complète. Recourez à des bibliothèques tierces uniquement lorsque la stdlib échoue véritablement — moins de dépendances signifie moins d'audits de sécurité, moins de conflits de versions et des builds plus rapides.
  8. Le code n'est pas terminé tant qu'il n'est pas gofmt-propre, ne compile pas et ne passe pas la vérification. Exécutez gofmt/goimports, go build, go vet, go test -race, et golangci-lint — faites-les devenir des passerelles CI ; le détecteur de course trouve des bugs invisibles à la revue. Lors de l'émission de code sans accès aux outils, maintenez la même barre manuellement : gardez-le formaté gofmt et incluez uniquement les importations que vous utilisez réellement (une importation inutilisée est une erreur de compilation — le glissement classique juste après avoir échangé un idiome pour un autre).
  9. Honorez le contrat de l'appelant, puis optimisez. Lorsqu'une tâche spécifie des identifiants, signatures, format de sortie ou types exacts, reproduisez-les exactement — même si vous les nommeriez ou structureriez différemment. Par défaut, choisissez la solution correcte la plus simple qui satisfait la spécification ; ajoutez de l'abstraction, de l'indirection ou des couches défensives uniquement lorsque la complexité de la tâche l'exige. Faire correspondre la surface requise fait partie de la correction — un renommage ou une restructuration gratuite brise les appelants et les tests.

Structure de Projet

Commencez simplement. Ajoutez de la structure uniquement lorsque le projet l'exige.

Binaire Unique (CLI ou petit service)

myapp/
├── go.mod
├── main.go              # package main, point d'entrée
├── app.go               # logique applicative centrale
├── app_test.go
└── internal/            # packages privés selon les besoins
    └── parser/
        ├── parser.go
        └── parser_test.go

Multi-Binaire / Service de Production

myproject/
├── go.mod
├── cmd/                 # points d'entrée — fonctions main() légères
│   ├── api-server/
│   │   └── main.go
│   └── worker/
│       └── main.go
├── internal/            # code applicatif privé (imposé par le compilateur)
│   ├── auth/
│   ├── user/            # package domaine : handler + service + repo
│   │   ├── handler.go
│   │   ├── service.go
│   │   ├── repository.go
│   │   └── model.go
│   ├── platform/        # transversal : db, cache, logging
│   │   ├── postgres/
│   │   └── redis/
│   └── middleware/
├── pkg/                 # OPTIONNEL : bibliothèques publiques réutilisables
├── api/                 # Spécifications OpenAPI, définitions protobuf
├── migrations/          # Fichiers de migration SQL
├── scripts/             # Outils de build, déploiement, développement
├── configs/             # Fichiers de configuration par défaut
└── Makefile

Règles clés :

  • internal/ est imposé par le compilateur Go — le code ici ne peut pas être importé par des modules externes.
  • cmd/*/main.go doit être léger : analyser les indicateurs, câbler les dépendances, appeler run(), gérer l'arrêt.
  • Regroupez par domaine/fonctionnalité, pas par couche technique. Évitez models/, controllers/, services/ — c'est une couche à la Java qui lutte contre le modèle de package de Go.
  • Évitez les packages utils/, helpers/, common/ — nommez les packages par ce qu'ils fournissent, car les noms vagues attirent du code non apparenté et rendent les importations dénuées de sens.
  • Un répertoire EST un package. Ne créez pas de répertoires juste pour l'organisation.

Conventions de Nommage

// Packages : courts, minuscules, un seul mot. Pas de tirets bas ni de mixedCaps.
package user      // bien
package userService // mal — mixedCaps

// Exporté : MixedCaps. Non exporté : mixedCaps. Les tirets bas sont légaux mais la
// communauté les traite comme un bug de style — ils signalent un code non idiomatique.
func ParseRequest()  // exporté
func parseHeader()   // non exporté

// Interfaces : suffixe méthode + "-er" pour les interfaces à méthode unique
type Reader interface { Read(p []byte) (n int, err error) }
type Validator interface { Validate() error }

// Getters : Owner(), pas GetOwner(). Setters : SetOwner().
func (u *User) Name() string       // getter — le préfixe "Get" est non-Go
func (u *User) SetName(n string)   // setter

// Acronymes : tout en majuscules. URL, HTTP, ID, API — pas Url, Http, Id, Api.
type HTTPClient struct{}
var userID int

// Variables d'erreur : ErrXxx. Types d'erreur : XxxError.
var ErrNotFound = errors.New("non trouvé")
type ValidationError struct { Field string; Message string }

// Contexte : premier paramètre, toujours nommé ctx. C'est une convention Go universelle
// qui rend la propagation du contexte instantanément reconnaissable dans n'importe quelle base de code.
func (s *Service) GetUser(ctx context.Context, id string) (*User, error)

Gestion des Erreurs

C'est le modèle le plus distinctif de Go. Maîtrisez-le.

// Vérifiez chaque erreur — enveloppez avec du contexte en utilisant %w
f, err := os.Open(name)
if err != nil {
    return fmt.Errorf("ouverture de la config %s : %w", name, err)
}
defer f.Close()

// errors.AsType — extraction d'erreur typée générique [Go 1.26+]
// Préféré à errors.As : type-safe, pas de variable pré-déclarée nécessaire.
if pathErr, ok := errors.AsType[*fs.PathError](err); ok {
    fmt.Println("échec au chemin :", pathErr.Path)
}

Règles clés :

  • return err sans contexte rend le débogage douloureux — enveloppez toujours avec fmt.Errorf("doing X: %w", err).
  • log.Fatal(err) dans le code de bibliothèque appelle os.Exit(1), sautant le nettoyage différé — retournez les erreurs aux appelants.
  • panic() est pour les bugs de programmeur, pas pour les conditions d'exécution — retournez les erreurs à la place.
  • Enveloppez les erreurs tierces avec %v (pas %w) pour éviter de coupler les appelants au type d'erreur sous-jacent.
  • Style de message d'erreur : minuscules, pas de ponctuation : fmt.Errorf("lecture du fichier de configuration : %w", err).

Voir references/errors-and-resilience.md pour les erreurs sentinelles, les types d'erreur personnalisés, errors.Join, les modèles de tentative, les circuit breakers et la dégradation gracieuse.


Essentiels de la Concurrence

Voir references/concurrency.md pour des modèles complets incluant errgroup, les pools de workers et le fan-out/fan-in. Règles de base :

  1. Utilisez le contexte pour l'annulation. Chaque goroutine doit vérifier ctx.Done() — sans cela, il n'y a aucun moyen de signaler "arrêtez le travail".
  2. Préférez errgroup à sync.WaitGroup brut. Regroupe l'attente + la collecte d'erreurs + l'annulation de contexte. Voir concurrency.md pour des exemples complets avec SetLimit.
  3. Protégez l'état partagé — canaux pour la communication, mutex quand c'est plus simple. Commentez ce que chaque mutex protège.
  4. Chaque goroutine a besoin d'un chemin d'arrêt. Pas de vérification d'annulation = goroutine qui fuit = fuite mémoire.
  5. Un panic dans une goroutine tue tout le processus. Récupérez dans les goroutines générées, ou utilisez sourcegraph/conc.

Primitives de synchronisation nouvelles :

sync.OnceValue / sync.OnceValues [Go 1.21+] — initialisation différée type-safe remplaçant sync.Once + variable de package :

var loadConfig = sync.OnceValues(func() ([]byte, error) {
    return os.ReadFile("config.json") // s'exécute exactement une fois, sûr depuis n'importe quelle goroutine
})
data, err := loadConfig() // les appels suivants retournent le résultat mis en cache

sync.WaitGroup.Go [Go 1.25+] — combine Add(1) + go func + Done() :

var wg sync.WaitGroup
wg.Go(func() { process(1) })
wg.Go(func() { process(2) })
wg.Wait()

Dimensionnement des canaux : non bufferisé (0) pour la synchronisation, bufferisé (1) pour les signaux, bufferisé (N) pour un travail connu et limité.


Interfaces

// Acceptez des interfaces, retournez des types concrets
type UserStore interface {
    GetUser(ctx context.Context, id string) (*User, error)
}
func NewService(store UserStore) *Service { return &Service{store: store} }

// Gardez les interfaces petites — 1-3 méthodes. Composez des plus grandes à partir de petites.
type ReadWriter interface { Reader; Writer }

// Définissez l'interface

Skills associés