Modifications apportées au langage
Go 1.17 comprend trois améliorations mineures apportées au langage.
- Conversions de slice en pointeur de tableau : Une expression s de type []T peut maintenant être convertie en pointeur de tableau de type *[N]T. Si a est le résultat d'une telle conversion, alors les indices correspondants qui sont dans la plage se réfèrent aux mêmes éléments sous-jacents*: &a[i] == &s[i] pour 0 <= i < N. La conversion panique si len(s) est inférieur à N.
- unsafe.Add : unsafe.Add(ptr, len) ajoute len à ptr et renvoie le pointeur mis à jour unsafe.Pointer(uintptr(ptr) + uintptr(len)).
- unsafe.Slice : pour l'expression ptr de type *T, unsafe.Slice(ptr, len) renvoie un slice de type []T dont le tableau sous-jacent commence à ptr et dont la longueur et la capacité sont len.
Ces améliorations ont été ajoutées pour simplifier l'écriture de code conforme aux règles de sécurité de unsafe.Pointer, mais les règles restent inchangées. En particulier, les programmes existants qui utilisent correctement unsafe.Pointer restent valides et les nouveaux programmes doivent toujours suivre les règles lorsqu'ils utilisent unsafe.Add ou unsafe.Slice.
Notez que la nouvelle conversion de pointeur de slice en pointeur de tableau est le premier cas dans lequel une conversion de type peut paniquer au moment de l'exécution. Les outils d'analyse qui supposent que les conversions de type ne peuvent jamais paniquer doivent être mis à jour pour prendre en compte cette possibilité.
Ports
Darwin
Comme annoncé dans les notes de publication de Go 1.16, Go 1.17 nécessite macOS 10.13 High Sierra ou une version ultérieure ; la prise en charge des versions précédentes a été interrompue.
Windows
Go 1.17 ajoute la prise en charge de l'architecture ARM 64 bits sous Windows (le port windows/arm64). Ce port prend en charge cgo.
OpenBSD
L'architecture MIPS 64 bits sur OpenBSD (le port openbsd/mips64) prend désormais en charge cgo.
Dans Go 1.16, sur les architectures ARM 64 bits x86 et 64 bits sur OpenBSD (les ports openbsd/amd64 et openbsd/arm64), les appels système sont effectués via la libc, au lieu d'utiliser directement les instructions machine. Dans Go 1.17, cela est également fait sur les architectures ARM 32 bits x86 et 32 bits sur OpenBSD (les ports openbsd/386 et openbsd/arm). Cela garantit la compatibilité avec les futures versions d'OpenBSD, en particulier avec OpenBSD 6.9 et les versions ultérieures, ce qui nécessite que les appels système soient effectués via la libc pour les binaires Go non statiques.
ARM64
Les programmes Go maintiennent désormais des pointeurs de trame de pile sur l'architecture ARM 64 bits sur tous les systèmes d'exploitation. Auparavant, il ne conservait les pointeurs de trame de pile que sur Linux, macOS et iOS.
Outils
Commandes Go
Lazy module loading
Si un module spécifie go 1.17 ou supérieur dans son fichier go.mod, ses exigences transitives sont désormais chargées paresseusement, évitant ainsi le besoin de télécharger ou de lire les fichiers go.mod pour les dépendances autrement non pertinentes. Pour prendre en charge le chargement paresseux, dans les modules Go 1.17, la commande go maintient des exigences explicites dans le fichier go.mod pour chaque dépendance qui fournit un package importé de manière transitive par n'importe quel package ou test dans le module.
Étant donné que le nombre d'exigences explicites supplémentaires dans le fichier go.mod peut être important, dans un module Go 1.17, les exigences nouvellement ajoutées sur les dépendances indirectes sont conservées dans un bloc require distinct du bloc contenant les dépendances directes.
Pour faciliter la mise à niveau vers le chargement différé, la sous-commande go mod tidy prend désormais en charge un indicateur -go pour définir ou modifier la version go dans le fichier go.mod. Pour activer le lazy loading d'un module existant sans modifier les versions sélectionnées de ses dépendances, exécutez :
Code Go : | Sélectionner tout |
go mod tidy -go=1.17
Par défaut, go mod tidy vérifie que les versions sélectionnées des dépendances pertinentes pour le module principal sont les mêmes versions qui seraient utilisées par la version précédente de Go (Go 1.16 pour un module qui spécifie go 1.17), et préserve les entrées go.sum requis par cette version, même pour les dépendances qui ne sont normalement pas requises par d'autres commandes.
L'indicateur -compat permet de remplacer cette version pour prendre en charge les versions plus anciennes (ou uniquement les plus récentes), jusqu'à la version spécifiée par la directive go dans le fichier go.mod. Pour ranger un module go 1.17 pour Go 1.17 uniquement, sans enregistrer les sommes de contrôle pour (ou vérifier la cohérence avec) Go 1.16 :
Code Go : | Sélectionner tout |
go mod tidy -compat=1.17
Notez que même si le module principal est rangé avec -compat=1.17, les utilisateurs qui ont besoin du module d'un module go 1.16 ou antérieur pourront toujours l'utiliser, à condition que les packages n'utilisent que des fonctionnalités de langage et de bibliothèque compatibles.
Commentaires sur l'obsolescence du module
Les auteurs de modules peuvent déprécier un module en ajoutant un // Deprecated: comment à go.mod, puis en marquant une nouvelle version. go get affiche désormais un avertissement si un module nécessaire pour construire des packages nommés sur la ligne de commande est obsolète. go list -m -u affiche les dépréciations pour toutes les dépendances (utilisez -f ou -json pour afficher le message complet). La commande go considère les différentes versions majeures comme des modules distincts, ce mécanisme peut donc être utilisé, par exemple, pour fournir aux utilisateurs des instructions de migration pour une nouvelle version majeure.
Compilateur
Go 1.17 implémente une nouvelle façon de passer les arguments et les résultats des fonctions en utilisant des registres au lieu de la pile. Ce travail est activé pour Linux, MacOS et Windows sur l'architecture x86 64 bits (les ports linux/amd64, darwin/amd64, windows/amd64). Pour un ensemble représentatif de packages et de programmes Go, l'analyse comparative effectuée par les équipes de Google a montré des améliorations de performances d'environ 5 % et une réduction typique de la taille binaire d'environ 2 %.
Cette modification n'affecte pas la fonctionnalité d'un code Go sécurisé. Cela peut affecter le code en dehors des directives de compatibilité avec un impact minimal. Pour maintenir la compatibilité avec les fonctions d'assemblage existantes, des fonctions d'adaptateur convertissant entre la nouvelle convention d'appel basée sur les registres et la convention d'appel précédente basée sur la pile (également appelée ABI wrappers) sont parfois utilisées. Ceci est principalement invisible pour les utilisateurs, à l'exception des fonctions d'assemblage dont les adresses sont prises dans Go. L'utilisation de reflect.ValueOf(fn).Pointer() (ou des approches similaires telles que via unsafe.Pointer) pour obtenir l'adresse d'une fonction d'assemblage renverra désormais l'adresse de l'encapsuleur ABI. Ceci est généralement inoffensif, sauf pour le code d'assemblage à usage spécial (tel que l'accès au stockage local de threads ou nécessitant un alignement de pile spécial). Les fonctions d'assemblage appelées indirectement à partir de Go via les valeurs func seront désormais créées via des wrappers ABI, ce qui peut entraîner une très faible surcharge de performances.
Le format des traces de pile du runtime (imprimées lorsqu'une panique non détectée se produit ou lorsque runtime.Stack est appelé) est amélioré. Auparavant, les arguments de la fonction étaient affichés sous forme de mots hexadécimaux en fonction de la disposition de la mémoire. Désormais, chaque argument du code source est imprimé séparément, séparé par des virgules. Les arguments de type agrégat (struct, tableau, chaîne, tranche, interface et complexe) sont délimités par des accolades. Une mise en garde est que la valeur d'un argument qui ne vit que dans un registre et n'est pas stocké en mémoire peut être inexacte. Les résultats (qui étaient généralement inexacts) ne sont plus affichés.
Source : Go