Zum Hauptinhalt Zur Navigation

Programmiersprache: Das ändert sich in Go 1.20

Am 1. Februar ist Go in der Version 1.20 erschienen. Wir geben eine Übersicht über die wichtigsten Neuerungen.
/ Tim Scheuermann
12 Kommentare News folgen (öffnet im neuen Fenster)
Go 1.20 ist veröffentlicht (Bild: Martin Wolf / Golem.de)
Go 1.20 ist veröffentlicht Bild: Martin Wolf / Golem.de

Das Go-Team hält den selbst gesetzten Zeitplan mit halbjährlichen Releases ein und hat den Release Candidate 3 für Go 1.20 veröffentlicht. Bis zum geplanten Release im Februar sind noch ein paar Tage Zeit, um sich die Änderungsliste(öffnet im neuen Fenster) anzusehen. Wir informieren über die interessantesten Neuerungen.

Unterstützung für Profile Guided Optimization

Der Go-Compiler unterstützt jetzt Profile Guided Optimization (PGO). Diese ist besonders für Server- und andere langlaufende Projekte interessant. Wird dem Compiler ein pprof -CPU-Profil zur Verfügung gestellt, werden die Stellen des Codes besonders gut optimiert, die häufig genutzt werden. Das Go-Team erwartet je nach Projekt eine um 3 bis 4 Prozent bessere Performance. Das mag zunächst bescheiden klingen, allerdings gibt es die Optimierung quasi gratis, wenn zur Performancemessung sowieso CPU-Profile angelegt werden.

Um ein Profil zu erstellen, wird das Programm entweder direkt über pprof gestartet oder bei einem langlaufenden Server per net/http/pprof -Paket eingebunden. Letztgenannte Methode bietet sich an, um Server zu überwachen. Der Profiler ist nur aktiv, wenn ein Client die Daten abfragt. Die entsprechende HTTP-Route sollte jedoch abgesichert werden und nicht im Internet abrufbar sein.

Beispiel für das direkte Anlegen eines CPU-Profils:

        
import "runtime/pprof"
[...]
profile, err := os.Create("profile.pgo")
if err != nil {
    log.Fatalln(err)
}
defer profile.Close()
if err := pprof.StartCPUProfile(profile); err != nil {
    log.Fatalln(err)
}
defer pprof.StopCPUProfile()

Anschließend lässt sich das Profil mit dem -pgo flag zur Optimierung verwenden: go build . -pgo="profile.pgo"

Laufzeit-Überprüfung von comparable Constraints

Typen, die als Schlüssel in Maps genutzt oder per == verglichen werden, müssen vergleichbar ( comparable ) sein. Das trifft auf die meisten primitiven Datentypen zu, allerdings nicht auf Slice- oder Funktionstypen. Als Sonderfall lassen sich auch Interface-Typen verwenden, wobei dann zur Laufzeit ein Check stattfindet, ob der tatsächlich übergebene Typ vergleichbar ist.

In generischen Funktionen versucht der Compiler diese Überprüfung während der Übersetzung, was fehlschlägt. Der Compiler ließ also keine Interface-Typen als generische Typen zu, wenn diese als Map-Schlüssel oder in einem Vergleich benutzt wurden. Mit Go 1.20 fällt diese Einschränkung weg.

Slice-zu-Array-Konvertierung

In Go 1.17 wurde die Möglichkeit eingeführt, ein Slice wieder in ein Array zu konvertieren. Slices sind Referenzen auf einen Teil eines Arrays. Der große Vorteil liegt dabei in der Flexibilität. Hat das unterliegende Array ausreichend Platz, können weitere Elemente angehängt werden, ohne dass die bestehenden Elemente in ein größeres Array kopiert werden.

Außerdem muss nicht jedes Mal das komplette Array kopiert werden, wenn es einer Funktion übergeben werden soll. Go hat von Anfang an die Möglichkeit, ein Slice von einem bestehenden Array zu erzeugen ( slice ):

        
array := [4]int{1, 2, 3, 4}
slice := array [:] // erzeugt ein Slice über das komplette Array

Umgekehrt war das lange nicht möglich. In Go 1.17 wurde die Möglichkeit zwar eingeräumt, die Syntax erinnert aber mehr an C als Go. Letztlich wurde lediglich der Type-Check beim Konvertieren des Slices zum Pointer eines Arrays geändert.

        
slice := []int{1, 2, 3, 4}
array := *(*[4]int)(slice)

Mit der neuen Version 1.20 wird die Syntax deutlich vereinfacht.

        
array := [4]int(slice)

Das Ziel-Array sollte hierbei kleiner oder gleich der Kapazität des Arrays sein, das slice zugrunde liegt. Andernfalls wird eine Runtime-Panic ausgelöst.

Kleine Änderungen

Das unsafe -Paket bekommt die drei Funktionen SliceData, String und StringData, die es Entwicklern ermöglichen, ohne Wissen über die internen Datenstrukturen direkt auf die Daten von Strings und Slices zuzugreifen. Bisher war dafür eine fehleranfällige Konvertierung in reflect.StringHeader oder reflect.SliceHeader notwendig.

Die Spezifikation legt nun fest, wie Implementierungen von Go zwei Structs oder Arrays vergleichen. Die einzelnen Felder oder Elemente werden in der Reihenfolge verglichen, in der sie im Quellcode definiert wurden. Außerdem wurde klargestellt, dass der Vergleich nur bis zum ersten Unterschied erfolgt und dass nicht immer die komplette Datenstruktur durchlaufen werden muss.

Go schaltet jetzt automatisch die CGo-Unterstützung ein, wenn auf dem System keine C-Toolchain installiert ist.

Ports

Go 1.20 hat nun experimentelle Unterstützung für FreeBSD auf RISC-V Chips. Außerdem weist das Team darauf hin, dass Go 1.20 die letzte Version mit Unterstützung für Windows 7, Windows 8, Windows Server 2008, Windows Server 2012, MacOS 10.13 und MacOS 10.14 wird. Ältere Versionen der genannten Systeme werden schon länger nicht mehr unterstützt.

Es ist jedoch weiterhin möglich, dass mit neueren Versionen von Go gebaute Programme auf älteren Betriebssystemversionen laufen. Das Team führt diesbezüglich nur keine Tests mehr durch.

Alte Zöpfe

Bisher war zum Bauen einer neuen Go-Version mindestens Version 1.4 erforderlich (die "Bootstrap-Version"). Go 1.4 war die letzte Version, bei der der Compiler selbst in C geschrieben war. Das Go-Team patchte diese Version noch notdürftig, um sie mit aktuellen C-Compilern kompatibel zu halten.

Zum Bauen der aktuellen Version war somit nur eine Zwischenversion erforderlich. Damit ist Schluss. Go 1.20 setzt Version 1.17 voraus. Das Build-Skript prüft die Version automatisch und verweigert den Dienst, falls diese zu alt ist. Ab sofort soll die Bootstrap-Version jedes Jahr angehoben werden, um dem Go-Team schnelleren Zugriff auf neue Features zu ermöglichen.

Kompatibilität

Wie immer wurden viele kleinere Änderungen an den Paketen vorgenommen. Weiterhin ist der Compiler aber mit Go 1.0 kompatibel, alte Programme lassen sich ohne Probleme mit der neuen Version bauen. Nachtrag vom 1. Februar 2023, 17:44 Uhr

Die Go-Version 1.20(öffnet im neuen Fenster) ist erschienen und kann hier heruntergeladen(öffnet im neuen Fenster) werden.


Relevante Themen