- Cette version améliore les littéraux de structures et l’inférence de types autour des méthodes génériques, et ajoute des fonctionnalités pratiques dans toute la bibliothèque standard, le runtime et la chaîne d’outils
- L’allocation mémoire spécialisée par taille réduit jusqu’à 30 % le coût de certaines allocations de moins de 80 octets ; les programmes intensifs en allocations devraient gagner environ 1 % de performances, avec une augmentation du binaire d’environ 60 Ko
encoding/json/v2est officiellement disponible, l’ancienencoding/jsonutilise aussi v2 en interne, et un package UUID standard ainsi que les signatures ML-DSA basées sur FIPS 204 sont ajoutés- Le profil
goroutineleak, les labels pprof dans les tracebacks,synctest.Sleeppour le temps virtuel et les serveurs de test HTTP en mémoire facilitent le diagnostic et les tests de concurrence - Les canaux de timers non bufferisés, l’épuisement automatique des corps de réponses HTTP et le renforcement des restrictions de
//go:linknamepeuvent affecter le code existant : une vérification de compatibilité avant le passage à Go 1.27 est nécessaire
Langage et système de types
- Les méthodes génériques, au cœur de Go 1.27, peuvent déclarer leurs propres paramètres de type indépendamment du receiver
- Auparavant, seules les fonctions de premier niveau pouvaient être génériques, si bien que les opérations appartenant à un type devaient aussi être écrites comme fonctions de package
- On peut définir sous forme de méthode une opération qui renvoie un type d’élément différent de celui de l’entrée, comme
Box[T].Map[U] - Les interfaces ne peuvent toujours pas déclarer de méthodes à paramètres de type, et les méthodes génériques ne peuvent pas non plus implémenter des interfaces
- Les clés de littéraux de structures peuvent utiliser non seulement des noms de champs de premier niveau, mais aussi des sélecteurs de champs valides
- Les champs promus depuis une structure embarquée peuvent être initialisés directement, comme dans
User{ID: 7}
- Les champs promus depuis une structure embarquée peuvent être initialisés directement, comme dans
- L’inférence de types de fonctions est étendue aux conversions et aux littéraux composés
- Comme dans
[]func([]int) int{first, last}, les arguments de type d’une fonction générique sont inférés à partir du type de fonction attendu - Auparavant, il fallait instancier explicitement, par exemple
first[int]etlast[int]
- Comme dans
Runtime et performances
- Le compilateur appelle des routines d’allocation spécialisées par taille qui réduisent jusqu’à 30 % le coût de certaines allocations mémoire de moins de 80 octets
- Le gain global attendu dans les programmes réellement intensifs en allocations est d’environ 1 %
- Aucune modification du code n’est nécessaire, mais le binaire grossit d’environ 60 Ko quelle que soit la charge de travail
- Il est possible de désactiver cette option avec
GOEXPERIMENT=nosizespecializedmalloc, mais ce choix sera supprimé dans Go 1.28
- Trois optimisations du compilateur activées par défaut sont ajoutées
- Une passe de flux de données known bits qui suit les bits dont on sait avec certitude qu’ils valent 0 ou 1 dans une valeur afin d’éliminer les opérations redondantes
- Le déplacement hors des boucles des calculs qui ne changent pas pendant l’itération
- La compilation des
switchéligibles en tables de correspondance, y compris avecfallthrough
- L’option expérimentale
GOEXPERIMENT=mapsplitgroupchange la disposition mémoire des groupes de maps deKVKVKVKVàKKKKVVVV; elle est désactivée par défaut - Le linker déplace les descripteurs de types et les itab dans une section dédiée
.go.type, et supprimetypelinksetitablinks- Comme
reflect.typelinksrenvoie des types plutôt que des offsets, les bibliothèques qui accèdent à ce symbole via//go:linknamepeuvent être affectées
- Comme
Diagnostic des goroutines et profiling
- Les modules dont
go.modindique Go 1.27 ou plus affichent les labelsruntime/pprofdans l’en-tête de goroutine des tracebacks- Le contexte ajouté avec
pprof.Do, comme{request: 42}, apparaît dans les crash dumps,SIGQUITet la sortie deruntime.Stack - Pour éviter l’exposition de labels sensibles dans les tracebacks,
GODEBUG=tracebacklabels=0reste disponible
- Le contexte ajouté avec
- Le détecteur de fuites de goroutines, fonctionnalité expérimentale de Go 1.26, devient un profil officiel
goroutineleak- Il lance le GC pour trouver les goroutines qui ne pourront jamais progresser, par exemple sur des channels ou des mutex, et affiche leurs piles
- Dans les services, il peut être collecté via l’endpoint
/debug/pprof/goroutineleak, sans nécessiterGOEXPERIMENT
Cryptographie et identifiants
- Le nouveau package crypto/mldsa implémente les signatures post-quantiques ML-DSA de FIPS 204
- Les trois ensembles de paramètres
MLDSA44,MLDSA65etMLDSA87arbitrent entre taille des clés, taille des signatures et niveau de sécurité - ML-DSA est également ajouté aux clés et signatures de
crypto/x509, ainsi qu’aux modes de signature TLS 1.3 decrypto/tls
- Les trois ensembles de paramètres
- Le nouveau package uuid de la bibliothèque standard génère et parse des UUID RFC 9562 à partir de nombres aléatoires cryptographiquement sûrs
uuid.New()choisit une méthode adaptée aux usages courants,NewV4()produit un UUID purement aléatoire etNewV7()un UUID ordonné par date de création- Les UUID construits à partir d’aléa sont comparables, ce qui permet d’utiliser directement
== - Les UUID v7, triables chronologiquement, conviennent bien comme clés de bases de données
JSON et API de traitement de données
- encoding/json/v2 et le bas niveau
encoding/json/jsontextsont disponibles sansGOEXPERIMENT=jsonv2- L’ancien
encoding/jsonv1 utilise aussi en interne l’implémentation v2 - Le comportement existant est conservé, hormis quelques formulations de messages d’erreur ; aucune migration n’est donc nécessaire
- En cas de problème de compatibilité,
GOEXPERIMENT=nojsonv2permet de restaurer l’implémentation v1 d’origine - Pour des raisons de performance, v2 ne trie pas les clés de map par défaut ; dans les tests nécessitant une sortie stable, il faut spécifier
json.Deterministic
- L’ancien
strings.CutLastetbytes.CutLastdécoupent une valeur selon le dernier séparateur- Si le séparateur est absent, ils renvoient toute l’entrée, une seconde partie vide et
false
- Si le séparateur est absent, ils renvoient toute l’entrée, une seconde partie vide et
- Le
Hasher[T]générique dehash/maphashdéfinit à la fois la stratégie de hachage et d’égalité d’une valeur- Des valeurs égales doivent impérativement avoir le même hash
ComparableHasher[T]est fourni pour les types comparables, et il est aussi possible d’implémenter des stratégies personnalisées, par exemple pour des chaînes insensibles à la casse
math/big.Int.Dividecalcule quotient et reste ensemble en appliquant explicitement un mode d’arrondi parmiTrunc,Floor,RoundetCeil- Le reste varie aussi selon le mode d’arrondi, ce qui compense dans le code financier et numérique les limites de la troncature vers zéro de
QuoetMod
- Le reste varie aussi selon le mode d’arrondi, ce qui compense dans le code financier et numérique les limites de la troncature vers zéro de
math/rand/v2.(*Rand).Ngénère, depuis sa propre source*Rand, un nombre aléatoire borné pour les types entiers ou duration
SIMD portable
- Le package expérimental simd fournit une API SIMD indépendante de la taille des vecteurs et s’active avec
GOEXPERIMENT=simd- Sur les environnements pris en charge, il compile vers de véritables instructions vectorielles matérielles ; sinon, il bascule vers une émulation en Go pur
- Le nombre de lanes de types comme
Float32sn’est pas fixe et suit la largeur matérielle de la machine
- La bibliothèque standard utilise déjà en interne les intrinsics
simd/archsimdMemHash32,MemHash64etStrHashdes maps Swiss Table sont réimplémentés sur cette nouvelle base SIMD
Tests déterministes
testing/synctest.Sleepfait avancer le temps virtuel et attend que toutes les goroutines soient stabilisées en une seule opération- Dans une bulle
synctest, le temps réel ne s’écoule pas : une attente de 2 secondes se termine immédiatement - Il remplace le code répétitif combinant auparavant
time.Sleepetsynctest.Wait
- Dans une bulle
httptest.NewTestServerexécute un serveur sur un réseau virtuel en mémoire au lieu d’utiliser un vrai port TCPsrv.Client()se connecte directement au handler via un pipe interne au processus- Le nettoyage étant automatique via
t.Cleanup,defer srv.Close()n’est plus nécessaire - Combiné à
testing/synctest, il permet de tester rapidement et de façon déterministe les allers-retours HTTP en temps virtuel
Réseau et changements de compatibilité
- Les channels renvoyés par
time.After,time.NewTimer,time.NewTicker, etc. deviennent toujours des channels synchrones non bufferisés- Le paramètre GODEBUG
asynctimerchan, qui restaurait l’ancien comportement bufferisé, est supprimé
- Le paramètre GODEBUG
- En HTTP/1,
http.Response.Body.Closelit le corps non consommé jusqu’à une limite prudente afin de faciliter la réutilisation de la connexion- Si vous comptiez sur
Closepour interrompre prématurément un gros téléchargement, il faut désactiver la réutilisation avecTransport.DisableKeepAlives
- Si vous comptiez sur
- Les serveurs HTTP/2 comprennent les priorités client de la RFC 9218 et traitent d’abord les streams à haute priorité
Server.DisableClientPriority = truepermet de restaurer l’ancien comportement round-robin
- Sous Windows et macOS,
crypto/x509.SystemCertPoolprend en chargeSSL_CERT_FILEetSSL_CERT_DIR- Si les variables sont définies, les certificats racines sont lus depuis le disque et le vérificateur Go est utilisé à la place des API de la plateforme
- Cela peut être désactivé avec
GODEBUG=x509sslcertoverrideplatform=0
- L’implémentation HTTP/2 auparavant incluse dans le fichier généré
h2_bundle.gode 12 226 lignes est remplacée par un vrai packagenet/http/internal/http2 net/httpajoute des hooks HTTP/3 enfichables avant exposition publique, et une partie de la suite de tests s’exécute en HTTP/3- Il n’existe pas encore d’API publique appelable, mais les bases d’un futur
http.Transportbasé sur QUIC sont incluses
- Il n’existe pas encore d’API publique appelable, mais les bases d’un futur
Chaîne d’outils
go testexécute par défaut la vérification vetstdversion, qui détecte l’utilisation de symboles de la bibliothèque standard plus récents que la version de Go déclarée dansgo.modgo doc pkg@versionpermet de consulter la documentation d’une version précise d’un modulego doc -exliste les exemples exécutables, et affiche le source quand on indique directement le nom d’un exemplego fixajoute les analyseurs de modernisationatomictypes,embedlit,slicesbackwardetunsafefuncswaitgroupest renommé enwaitgroupgoetfmtappendfest supprimé
- Dans les modules Go 1.27 ou plus,
go mod tidyfusionne les blocsrequiredispersés en deux blocs pour dépendances directes et indirectes, tout en conservant les commentaires go tool trace -http=:6060ne se lie qu’à localhost si seul un port est fourni ; pour un accès externe, il faut spécifier l’adresse- La commande
gosupprime la prise en charge du système de gestion de versions Bazaar (bzr) compile,link,asm,cgo,coveretpackprennent en charge les fichiers de réponse (@file) au format GCC afin de contourner les limites de longueur de ligne de commande
Unicode et périmètre de sécurité
- Les données Unicode de la bibliothèque standard passent de Unicode 15 à Unicode 17
- Les caractères ajoutés dans Unicode 16 sont eux aussi correctement classés comme symboles et caractères imprimables
- Un problème permettant de sortir de la racine via
os.Root.ReadDiretReaddirest corrigé - L’utilisation non approuvée de
//go:linknamedevient plus difficile- La directive
linknamestdmarque les linknames importables uniquement par la bibliothèque standard - Le linker vérifiant aussi l’accès par linkname aux symboles d’assembly, le code dépendant de symboles internes non officiels doit être testé tôt
- La directive
1 commentaires
Avis sur Lobste.rs
Peut-être la meilleure version à ce jour. SIMD, uuid, jsonv2 arrivent enfin
C’est un peu hors sujet, mais c’est un bon exemple des bugs qui apparaissent quand on traite tout comme une chaîne sans tenir compte du contrat et des liens entre les méthodes d’une interface
Equalignore la casse, maisHashutilise la valeur convertie en minuscules. OrEqualFoldetToLowerne définissent pas la même relation d’équivalencehttps://github.com/golang/go/issues/52204
"\u017F"(ſ, s long) et"s"sont égaux avecEqualFold, mais leurs résultats respectifs aprèsToLowerdiffèrent. Donc, si l’on insère"s"puis"ſ", le hachage est différent et l’élément est inséré séparémentLe plus amusant, c’est que la documentation met justement en garde contre ce cas
https://github.com/golang/go/…
https://github.com/golang/go/…
Content que quelqu’un ait repris là où Anton s’était arrêté
J’aime Go, mais je me demande si la syntaxe de Go est assez élégante pour continuer à ajouter ce genre de fonctionnalités à chaque version
func (b Box[T]) Map[U any](f func(T) U) Box[U] {À l’inverse, la verbosité de Go et de Zig a l’avantage de ne pas obliger à faire défiler ailleurs pour retrouver la définition du receveur. Aux sites d’appel, que l’on peut considérer comme plus importants que les définitions, tout se ressemble à peu près et il n’est pas non plus nécessaire de préciser les types
J’ai quitté Go pendant un moment, mais jsonv2 m’intéresse. Cela dit, s’il devient la valeur par défaut, je me demande si Go ne rompt pas la promesse de compatibilité qu’il tient depuis longtemps
encoding/json/v2, donc il faut le choisir explicitement. L’ancienencoding/jsonutilise v2 en interne, mais garantit le comportement précédent, et jsonv2 fournit aussi des options pour reproduire les comportements exceptionnels de v1, donc cela ne rompt pas la promesse de compatibilité