Changements dans le langage
Génériques
Go 1.18 inclut une implémentation de fonctionnalités génériques telles que décrites par la proposition de paramètres de type. Cela inclut des modifications majeures - mais entièrement rétrocompatibles - du langage.
Ces nouveaux changements de langage ont nécessité une grande quantité de nouveau code qui n'a pas été testé de manière significative dans les paramètres de production. Cela ne se produira que lorsque de plus en plus de personnes écriront et utiliseront du code générique. L'équipe est persuadée que cette fonctionnalité est bien implémentée et de haute qualité. Cependant, contrairement à la plupart des aspects de Go, elle ne peut pas étayer cette croyance par une expérience du monde réel. Par conséquent, bien qu'elle encourage l'utilisation de génériques là où cela a du sens, elle recommande de faire preuve de prudence lors du déploiement de code générique en production.
Bien que l'équipe pense que les nouvelles fonctionnalités du langage sont bien conçues et clairement spécifiées, il est possible quelle ait fait des erreurs. Elle tient à souligner que la garantie de compatibilité Go 1 dit « S'il devient nécessaire de corriger une incohérence ou une incomplétude dans la spécification, la résolution du problème pourrait affecter le sens ou la légalité des programmes existants. Nous nous réservons le droit de résoudre ces problèmes, y compris la mise à jour les implémentations ». Elle dit également « Si un compilateur ou une bibliothèque a un bogue qui viole la spécification, un programme qui dépend du comportement bogué peut planter si le bogue est corrigé. Nous nous réservons le droit de corriger ces bogues ». En d'autres termes, il est possible qu'il y ait du code utilisant des génériques qui fonctionneront avec la version 1.18 mais se briseront dans les versions ultérieures. L'équipe ne prévoit pas et ne s'attend pas à apporter un tel changement. Cependant, casser les programmes 1.18 dans les versions futures peut devenir nécessaire pour des raisons que nous ne pouvons pas prévoir aujourd'hui. L'équipe assure qu'elle minimisera autant que possible une telle casse, mais ne peut pas garantir que la casse sera nulle.
Voici une liste des changements les plus visibles :
- La syntaxe des déclarations de fonction et de type accepte désormais les paramètres de type.
- Les fonctions et les types paramétrés peuvent être instanciés en les faisant suivre d'une liste d'arguments de type entre crochets.
- Le nouveau jeton ~ a été ajouté à l'ensemble des opérateurs et de la ponctuation.
- La syntaxe des types d'interface permet désormais l'incorporation de types arbitraires (pas seulement les noms de type des interfaces) ainsi que les éléments de type union et ~T. De telles interfaces ne peuvent être utilisées que comme contraintes de type. Une interface définit désormais un ensemble de types ainsi qu'un ensemble de méthodes.
- Le nouvel identifiant prédéclaré any est un alias pour l'interface vide. Il peut être utilisé à la place de interface{}.
- Le nouvel identificateur prédéclaré comparable est une interface qui désigne l'ensemble de tous les types qui peuvent être comparés en utilisant == ou !=. Il ne peut être utilisé que comme (ou incorporé dans) une contrainte de type.
L'implémentation actuelle des génériques présente les limitations connues suivantes*:
- Le compilateur Go ne peut pas gérer les déclarations de type à l'intérieur de fonctions ou de méthodes génériques. Nous espérons fournir un support pour cette fonctionnalité dans Go 1.19.
- Le compilateur Go n'accepte pas les arguments de type paramètre type avec les fonctions prédéclarées real, imag et complex. Nous espérons supprimer cette restriction dans Go 1.19.
- Le compilateur Go ne prend en charge l'appel d'une méthode m sur une valeur x de type de paramètre de type P que si m est explicitement déclaré par l'interface de contrainte de P. De même, les valeurs de méthode x.m et les expressions de méthode P.m ne sont également prises en charge que si m est explicitement déclaré par P, même si m peut être dans l'ensemble de méthodes de P en raison du fait que tous les types de P implémentent m. Nous espérons supprimer cette restriction dans Go 1.19.
- Le compilateur Go ne prend pas en charge l'accès à un champ struct x.f où x est du type de paramètre de type même si tous les types du jeu de types du paramètre de type ont un champ f. Nous pouvons supprimer cette restriction dans Go 1.19.
- L'intégration d'un paramètre de type ou d'un pointeur vers un paramètre de type en tant que champ sans nom dans un type struct n'est pas autorisée. De même, l'intégration d'un paramètre de type dans un type d'interface n'est pas autorisée. On ne sait pas encore si ceux-ci seront autorisés.
- Un élément union avec plus d'un terme ne peut pas contenir un type d'interface avec un ensemble de méthodes non vide. On ne sait pas si cela sera jamais autorisé pour le moment.
« Les génériques représentent également un grand changement pour l'écosystème Go. Bien que nous ayons mis à jour plusieurs outils de base avec prise en charge des génériques, il reste encore beaucoup à faire. Il faudra du temps pour que les outils, la documentation et les bibliothèques restants rattrapent ces changements de langage ».
Outils
Fuzzing
Go 1.18 inclut une implémentation du fuzzing. Pour mémoire, le fuzzing est une technique pour tester des logiciels. L'idée est d'injecter des données aléatoires dans les entrées d'un programme. Si le programme échoue, alors il y a des défauts à corriger.
« Veuillez noter que le fuzzing peut consommer beaucoup de mémoire et peut avoir un impact sur les performances de votre machine pendant son exécution. Sachez également que le moteur de fuzzing écrit des valeurs qui étendent la couverture des tests dans un répertoire de cache fuzz dans $GOCACHE/fuzz pendant son exécution. Il n'y a actuellement aucune limite au nombre de fichiers ou au nombre total d'octets pouvant être écrits dans le cache fuzz, il peut donc occuper une grande quantité de stockage (éventuellement plusieurs Go) ».
Commandes Go
go get
go get ne construit ni n'installe plus de packages en mode module-aware. go get est désormais dédié à l'ajustement des dépendances dans go.mod. En effet, l'indicateur -d est toujours activé. Pour installer la dernière version d'un exécutable en dehors du contexte du module actuel, utilisez go install example.com/cmd@latest. N'importe quelle requête de version peut être utilisée à la place de latest. Cette forme d'installation go a été ajoutée dans Go 1.16, de sorte que les projets prenant en charge des versions plus anciennes peuvent avoir besoin de fournir des instructions d'installation pour go install et go get. go get signale maintenant une erreur lorsqu'il est utilisé en dehors d'un module, car il n'y a pas de fichier go.mod à mettre à jour. En mode GOPATH (avec GO111MODULE=off), allez toujours compiler et installer les packages, comme avant.
go.mod et go.sum
Les sous-commandes go mod graph, go mod vendor, go mod verify et go mod why ne mettent plus automatiquement à jour les fichiers go.mod et go.sum
go version
La commande go intègre désormais les informations de contrôle de version dans les binaires. Elle inclut la révision actuellement extraite, l'heure de validation et un indicateur indiquant si des fichiers modifiés ou non suivis sont présents. Les informations de contrôle de version sont intégrées si la commande go est invoquée dans un répertoire d'un référentiel Git, Mercurial, Fossil ou Bazaar, et que le package principal et son module principal se trouvent dans le même référentiel. Ces informations peuvent être omises à l'aide de l'indicateur -buildvcs=false.
De plus, la commande go intègre des informations sur la construction, y compris les balises de construction et d'outil (définies avec -tags), les drapeaux du compilateur, de l'assembleur et de l'éditeur de liens (comme -gcflags), si cgo a été activé et, le cas échéant, les valeurs de la variables d'environnement cgo (comme CGO_CFLAGS). Les informations de VCS et de construction peuvent être lues avec les informations de module à l'aide du fichier go version -m ou runtime/debug.ReadBuildInfo (pour le binaire en cours d'exécution) ou du nouveau package debug/buildinfo.
Le format de données sous-jacent des informations de construction intégrées peut changer avec les nouvelles versions de go, de sorte qu'une ancienne version de go peut ne pas gérer les informations de construction produites avec une version plus récente de go. Pour lire les informations de version d'un binaire construit avec go 1.18, utilisez la commande go version et le package debug/buildinfo de go 1.18+.
go mod download
Si le fichier go.mod du module principal spécifie go 1.17 ou supérieur, go mod download sans arguments télécharge désormais le code source uniquement pour les modules explicitement requis dans le fichier go.mod du module principal. (Dans un module go 1.17 ou supérieur, cet ensemble comprend déjà toutes les dépendances nécessaires pour créer les packages et les tests dans le module principal.) Pour télécharger également le code source des dépendances transitives, utilisez go mod download all.
go mod vendor
La sous-commande go mod vendor prend désormais en charge un indicateur -o pour définir le répertoire de sortie. (D'autres commandes go sont toujours lues à partir du répertoire du fournisseur à la racine du module lors du chargement des packages avec -mod=vendor, donc l'utilisation principale de cet indicateur est pour les outils tiers qui ont besoin de collecter le code source du package.)
go mod tidy
La commande go mod tidy conserve désormais des sommes de contrôle supplémentaires dans le fichier go.sum pour les modules dont le code source est nécessaire pour vérifier que chaque package importé est fourni par un seul module dans la liste de construction. Étant donné que cette condition est rare et que le fait de ne pas l'appliquer entraîne une erreur de construction, cette modification n'est pas conditionnée à la version go dans le fichier go.mod du module principal.
go work
La commande go prend désormais en charge un mode "Espace de travail". Si un fichier go.work est trouvé dans le répertoire de travail ou un répertoire parent, ou si un fichier est spécifié à l'aide de la variable d'environnement GOWORK, la commande go passe en mode espace de travail. En mode espace de travail, le fichier go.work sera utilisé pour déterminer l'ensemble des modules principaux utilisés comme racines pour la résolution des modules, au lieu d'utiliser le fichier go.mod normalement trouvé pour spécifier le module principal unique.
Environnement d'exécution
Le collecteur mémoire inclut désormais des sources de travail de collecteur mémoire hors tas (par exemple, l'analyse de la pile) lors de la détermination de la fréquence d'exécution. Par conséquent, la surcharge du collecteur mémoire est plus prévisible lorsque ces sources sont importantes. Pour la plupart des applications, ces changements seront négligeables*; cependant, certaines applications Go peuvent désormais utiliser moins de mémoire et consacrer plus de temps à la récupération de place, ou vice versa, qu'auparavant. La solution de contournement prévue consiste à modifier GOGC si nécessaire.
Le runtime restitue désormais plus efficacement la mémoire au système d'exploitation et a donc été réglé pour fonctionner de manière plus agressive.
Go 1.17 améliorait généralement le formatage des arguments dans les traces de pile, mais pouvait imprimer des valeurs inexactes pour les arguments passés dans les registres. Ceci est amélioré dans Go 1.18 en imprimant un point d'interrogation (?) après chaque valeur qui peut être inexacte.
La fonction intégrée append utilise désormais une formule légèrement différente pour décider de la croissance d'une tranche lorsqu'elle doit allouer un nouveau tableau sous-jacent. La nouvelle formule est moins sujette à des transitions soudaines dans le comportement d'allocation.
20*% d'amélioration des performances
« Les utilisateurs d'Apple M1, ARM64 et PowerPC64 se réjouissent ! Go 1.18 inclut des améliorations des performances du processeur allant jusqu'à 20 % en raison de l'extension de la convention d'appel ABI de registre de Go 1.17 à ces architectures. Juste pour souligner la taille de cette version, une amélioration des performances de 20*% est le quatrième titre le plus important*! »
Source : note de version