Changements apportés au langage
Go 1.22 apporte deux changements aux boucles "for".
- Auparavant, les variables déclarées par une boucle "for" étaient créées une seule fois et mises à jour à chaque itération. Dans Go 1.22, chaque itération de la boucle crée de nouvelles variables, afin d'éviter les bogues de partage accidentel. L'outil d'aide à la transition décrit dans la proposition continue de fonctionner de la même manière que dans Go 1.21.
- Les boucles "For" peuvent désormais porter sur des nombres entiers. Par exemple :
Code : Sélectionner tout 1
2
3
4
5
6
7
8
9
10package main import "fmt" func main() { for i := range 10 { fmt.Println(10 - i) } fmt.Println("go1.22 has lift-off!") }
Go 1.22 inclut un aperçu d'un changement de langage envisagé pour une future version de Go : les itérateurs de type "range-over-function". Construire avec GOEXPERIMENT=rangefunc permet d'activer cette fonctionnalité.
Outils
Commande Go
Les commandes dans les workspace peuvent maintenant utiliser un répertoire vendor contenant les dépendances de l'espace de travail. Le répertoire est créé par go work vendor, et utilisé par les commandes build lorsque le drapeau -mod est positionné à vendor, ce qui est le cas par défaut lorsqu'un répertoire vendor de l'espace de travail est présent.
Notez que le contenu du répertoire vendor pour un workspace est différent de celui d'un module unique : si le répertoire à la racine d'un workspace contient également l'un des modules du workspace, son répertoire vendor peut contenir les dépendances soit du workspace, soit du module, mais pas les deux.
go get n'est plus supporté en dehors d'un module dans l'ancien mode GOPATH (c'est-à-dire avec GO111MODULE=off). Les autres commandes de construction, telles que go build et go test, continueront à fonctionner indéfiniment pour les programmes GOPATH hérités.
go mod init ne tente plus d'importer les exigences des modules à partir de fichiers de configuration pour d'autres outils de distribution (tels que Gopkg.lock).
go test -cover imprime maintenant des résumés de couverture pour les paquets couverts qui n'ont pas leurs propres fichiers de test. Avant Go 1.22, une exécution de go test -cover pour un tel paquetage produisait le rapport suivant
? mymod/mypack [no test files]
et maintenant avec Go 1.22, les fonctions du paquet sont traitées comme non couvertes :
mymod/mypack couverture : 0,0 % of statements
Notez que si un paquet ne contient aucun code exécutable, on ne peut pas indiquer un pourcentage de couverture significatif ; pour de tels paquets, l'outil go continuera à indiquer qu'il n'y a pas de fichiers de test.
Trace
L'interface web de l'outil de traçage a été légèrement rafraîchie dans le cadre du travail de support du nouveau traceur, en résolvant plusieurs problèmes et en améliorant la lisibilité de diverses sous-pages. L'interface web permet désormais d'explorer les traces dans une vue orientée thread. Le visualiseur de traces affiche désormais la durée complète de tous les appels système.
Ces améliorations ne s'appliquent qu'à la visualisation des traces produites par des programmes construits avec Go 1.22 ou une version plus récente. Une prochaine version apportera certaines de ces améliorations aux traces produites par des versions plus anciennes de Go.
Vet
- Références aux variables de boucle
Le comportement de l'outil vet a changé pour s'adapter à la nouvelle sémantique (voir ci-dessus) des variables de boucle dans Go 1.22. Lors de l'analyse d'un fichier qui nécessite Go 1.22 ou plus récent (en raison de son fichier go.mod ou d'une contrainte de construction par fichier), vetcode> ne signale plus les références aux variables de boucle à l'intérieur d'un littéral de fonction qui pourrait survivre à l'itération de la boucle. Dans Go 1.22, les variables de boucle sont créées à nouveau pour chaque itération, donc de telles références ne risquent plus d'utiliser une variable après qu'elle ait été mise à jour par la boucle. - Nouveaux avertissements pour les valeurs manquantes après l'append
L'outil vet signale désormais les appels à append qui ne transmettent aucune valeur à ajouter à la tranche, tels que slice = append(slice). Une telle déclaration n'a aucun effet, et l'expérience a montré que c'est presque toujours une erreur. - Nouveaux avertissements pour le report de time.Since
L'outil vet signale maintenant un appel non différé à time.Since(t) à l'intérieur d'une déclaration defer. Cela équivaut à appeler time.Now().Sub(t) avant l'instruction de report, et non pas lorsque la fonction reportée est appelée. Dans presque tous les cas, le code correct exige de différer l'appel à time.Since. Par exemple :Code : Sélectionner tout 1
2
3
4
5
6
7t := time.Now() defer log.Println(time.Since(t)) // non-deferred call to time.Since tmp := time.Since(t); defer log.Println(tmp) // equivalent to the previous defer defer func() { log.Println(time.Since(t)) // a correctly deferred call to time.Since }()
- Nouveaux avertissements pour les paires clé-valeur non concordantes dans les appels à log/slog
L'outil vet signale désormais les arguments non valides dans les appels aux fonctions et méthodes du paquetage de journalisation structuré, log/slog, qui acceptent des paires clé/valeur alternées. Il signale les appels où un argument dans une position clé n'est ni une chaîne ni un slog.Attr, et où une clé finale n'a pas de valeur.
Temps d'exécution
Le Temps d'exécution (runtime) conserve désormais les métadonnées de garbage collection basées sur les types plus près de chaque objet du tas, ce qui améliore les performances CPU (latence ou débit) des programmes Go de 1 à 3 %. Ce changement réduit également la surcharge mémoire de la majorité des programmes Go d'environ 1 % en dédupliquant les métadonnées redondantes. Certains programmes peuvent voir une amélioration plus faible car ce changement ajuste les limites des classes de taille de l'allocateur de mémoire, de sorte que certains objets peuvent être déplacés vers le haut d'une classe de taille.
Une conséquence de ce changement est que les adresses de certains objets qui étaient auparavant toujours alignées sur une limite de 16 octets (ou plus) ne seront plus alignées que sur une limite de 8 octets. Certains programmes qui utilisent des instructions d'assemblage exigeant que les adresses mémoire soient alignées sur plus de 8 octets et qui s'appuient sur le comportement d'alignement précédent de l'allocateur de mémoire peuvent être interrompus, mais ces programmes devraient être rares. Ces programmes peuvent être compilés avec GOEXPERIMENT=noallocheaders pour revenir à l'ancienne disposition des métadonnées et restaurer le comportement d'alignement précédent, mais les propriétaires de paquets doivent mettre à jour leur code assembleur pour éviter l'hypothèse d'alignement, car cette solution de contournement sera supprimée dans une prochaine version.
Sur le port Windows/amd64, les programmes qui lient ou chargent des bibliothèques Go construites avec -buildmode=c-archive ou -buildmode=c-shared peuvent maintenant utiliser la fonction SetUnhandledExceptionFilter Win32 pour attraper les exceptions qui ne sont pas gérées par le runtime Go. Notez que ceci était déjà supporté sur le port windows/386.
Compilateur
Les compilateurs PGO (Profile-guided Optimization) peuvent maintenant dévirtualiser une plus grande proportion d'appels que ce qui était possible auparavant. La plupart des programmes d'un ensemble représentatif de programmes Go voient maintenant entre 2 et 14% d'amélioration grâce à l'activation de PGO.
Le compilateur intercale désormais la dévirtualisation et l'inlining, de sorte que les appels de méthodes d'interface sont mieux optimisés.
Go 1.22 inclut également un aperçu d'une implémentation améliorée de la phase d'inlining du compilateur qui utilise des heuristiques pour augmenter l'inlining aux sites d'appel jugés "importants" (par exemple, dans les boucles) et décourager l'inlining aux sites d'appel jugés "non importants" (par exemple, sur les chemins de panique). La construction avec GOEXPERIMENT=newinliner active la nouvelle heuristique des sites d'appel..
L'éditeur de liens
Les drapeaux -s et -w de l'éditeur de liens se comportent désormais de manière plus cohérente sur toutes les plateformes. Le drapeau -w supprime la génération des informations de débogage DWARF. L'option -s supprime la génération de la table des symboles. L'indicateur -s implique également l'indicateur -w, qui peut être annulé avec -w=0, c'est-à-dire que -s -w=0 génère un binaire avec les informations de débogage DWARF, mais sans la table des symboles.
Sur les plates-formes ELF, le drapeau -B de l'éditeur de liens accepte désormais une forme spéciale : avec -B gobuildid, l'éditeur de liens génère un identifiant de compilation GNU (la note ELF NT_GNU_BUILD_ID) dérivé de l'identifiant de compilation Go.
Sous Windows, lors de la construction avec -linkmode=internal, l'éditeur de liens préserve désormais les informations SEH des fichiers objets C en copiant les sections .pdata et .xdata dans le binaire final. Cela facilite le débogage et le profilage des binaires à l'aide d'outils natifs, tels que WinDbg. Notez que jusqu'à présent, les gestionnaires d'exception SEH des fonctions C n'étaient pas honorés, donc ce changement peut entraîner un comportement différent de certains programmes. L'option -linkmode=external n'est pas affectée par ce changement, car les linkers externes préservent déjà les informations SEH.
Base de démarrage (Bootstrap)
Comme mentionné dans les notes de version de Go 1.20, Go 1.22 requiert maintenant la version finale de Go 1.20 ou plus récente pour le bootstrap. Il est prévu que Go 1.24 nécessitera la version finale de Go 1.22 ou une version ultérieure pour le bootstrap.
Bibliothèque de base
Nouveau paquet math/rand/v2
Go 1.22 inclut le premier paquetage "v2" dans la bibliothèque standard, math/rand/v2. Les changements les plus importants sont les suivants :
- La méthode Read, dépréciée dans math/rand, n'a pas été reprise dans math/rand/v2 (elle reste disponible dans math/rand). La grande majorité des appels à Read devraient utiliser Read de crypto/rand à la place. Sinon, un Read personnalisé peut être construit à l'aide de la méthode Uint64.
- Le générateur global auquel accèdent les fonctions de premier niveau est inconditionnellement alimenté de manière aléatoire. L'API ne garantissant aucune séquence fixe de résultats, des optimisations telles que les états de générateur aléatoire par thread sont désormais possibles.
- L'interface Source possède désormais une seule méthode Uint64 ; il n'existe pas d'interface Source64.
- De nombreuses méthodes utilisent désormais des algorithmes plus rapides qu'il n'était pas possible d'adopter dans math/rand parce qu'ils modifiaient les flux de sortie.
- Les fonctions et méthodes de haut niveau Intn, Int31, Int31n, Int63 et Int64n de math/rand sont orthographiées de manière plus idiomatique dans math/rand/v2 : IntN, Int32, Int32N, Int64 et Int64N. Il existe également de nouvelles fonctions et méthodes de haut niveau : Uint32, Uint32N, Uint64, Uint64N, Uint et UintN.
- La nouvelle fonction générique N est semblable à Int64N ou Uint64N, mais elle fonctionne pour n'importe quel type d'entier. Par exemple, une durée aléatoire de 0 à 5 minutes est rand.N(5*time.Minute).
- Le générateur LFSR de Mitchell & Reeds fourni par la Source de math/rand a été remplacé par deux sources de générateurs pseudo-aléatoires plus modernes : ChaCha8 PCG. ChaCha8 est un nouveau générateur de nombres aléatoires cryptographiquement fort, à peu près similaire au PCG en termes d'efficacité. ChaCha8 est l'algorithme utilisé pour les fonctions de haut niveau dans math/rand/v2. Depuis Go 1.22, les fonctions de haut niveau de math/rand (lorsqu'elles ne sont pas explicitement semées) et le moteur d'exécution de Go utilisent également ChaCha8 pour l'aléatoire.
Il est prévu d'inclure un outil de migration d'API dans une prochaine version, probablement Go 1.23.
Nouveau paquetage go/version
Le nouveau paquetage go/version implémente des fonctions pour valider et comparer les chaînes de version de Go.
Modèles de routage améliorés
Le routage HTTP dans la bibliothèque standard est maintenant plus expressif. Les motifs utilisés par net/http.ServeMux ont été améliorés pour accepter les méthodes et les caractères génériques.
L'enregistrement d'un gestionnaire avec une méthode, comme "POST /items/create", restreint les invocations du gestionnaire aux requêtes avec la méthode donnée. Un motif avec une méthode est prioritaire sur un motif correspondant sans méthode. Dans un cas particulier, l'enregistrement d'un gestionnaire avec "GET" l'enregistre également avec "HEAD".
Les caractères génériques dans les motifs, comme /items/{id}, correspondent à des segments du chemin d'accès à l'URL. La valeur réelle du segment est accessible en appelant la méthode Request.PathValue. Un caractère générique se terminant par "...", comme /files/{chemin...}, doit se trouver à la fin d'un motif et correspond à tous les segments restants.
Un motif qui se termine par "/" correspond à tous les chemins qui ont ce préfixe, comme toujours. Pour obtenir une correspondance avec le motif exact, y compris la barre oblique finale, terminez le motif par {$}, comme dans /exact/match/{$}.
Si deux motifs se chevauchent dans les requêtes auxquelles ils correspondent, le motif le plus spécifique est prioritaire. Si aucun des deux n'est plus spécifique, les motifs entrent en conflit. Cette règle généralise les règles de préséance originales et maintient la propriété selon laquelle l'ordre dans lequel les motifs sont enregistrés n'a pas d'importance.
Ce changement rompt la compatibilité ascendante de quelques façons, certaines évidentes - les motifs avec "{" et "}" se comportent différemment - et d'autres moins - le traitement des chemins d'accès échappés a été amélioré. Le changement est contrôlé par un champ GODEBUG nommé httpmuxgo121. Définissez httpmuxgo121=1 pour rétablir l'ancien comportement.
Source : Note de mise à jour Go 1.22
Et vous ?
Quel est votre avis sur cette nouvelle version de Go ?
Voir aussi :
Go 1.21 apporte des améliorations au niveau du langage, le nouveaux paquets de bibliothèque standard, PGO GA, et une compatibilité ascendante et descendante dans la chaîne d'outils
Enquête sur le langage Go: les devs sont intéressés par les outils IA/ML qui améliorent la qualité, la fiabilité et les performances de leur code. Ils sont sur Linux et macOS pour la plupart
Python est facile. Go est simple. Simple != Facile. Python et Go ont des qualités distinctes qui peuvent se compléter, par Preslav Rachev, ingénieur en informatique