Heute ist Wochenende, obwohl es nur ein Tag ist. Lassen Sie mich einige Neuigkeiten zu Go1.17 mit Ihnen teilen. Erwerben Sie jeden Tag eine Fähigkeit, Fische anzulocken!
In der Go-Sprache enthält ein Slice einen Verweis auf sein Hintergrundarray, unabhängig davon, ob das Array irgendwo als unabhängige Variable existiert oder nur ein anonymes Array ist, das zur Unterstützung des Slicings zugewiesen ist.
Die Grundstruktur des Slicings ist wie folgt:
// runtime/slice.go type slice struct { array unsafe.Pointer // 指向底层数组的指针 len int // 长度 cap int // 容量 }
Die aktuelle Art und Weise, wie Slicing Arrays unterstützt, kann beim Slicing zu interessanten Speicherlecks oder überraschenden Änderungen an Ihrem Slicing führen.
Ein weiterer sehr wichtiger Punkt ist, dass es in Go 1.16 und früher keine sichere Methode zum Konvertieren vom Slice-Typ in den Array-Typ gibt, was ziemlich hilflos ist.
Wir können dies nur tun, indem wir die Standardbibliothek „reflect“ oder „unsafe“ aufrufen und unsicheren Code schreiben:
(*[10]byte)(unsafe.Pointer(&b[0]))
Das ist natürlich nicht elegant. Der Beamte rät von der Verwendung von „unsafe“ ab. Sobald die Verarbeitung fehlschlägt, kann dies zu schwerwiegenden Folgen führen Fehler und ist relativ unkontrollierbar.
Tatsächlich äußerten einige Leute bereits 2009, kurz nach der Veröffentlichung von Go (lange vor der Veröffentlichung von Go 1.0), relevante Zweifel und hofften, dieses Problem zu lösen:
Schließlich, im kommenden Go 1.17, dies Wird durch eine Reihe von Änderungen ermöglicht, beginnend mit Commit-ID #1c268431f4, der aktualisierten Spezifikation:
Die Beschreibung hierfür in der neuen Spezifikation ist unkompliziert:
Wenn das Slice länger als das Array ist, bedeutet das, dass Ihr Array nicht auf alle unterstützenden Arrays des ursprünglichen Slice zugreifen kann.Konvertieren eines Slice in einen Array-Zeiger Gibt einen Zeiger auf das zugrunde liegende Array des Slice zurück. Wenn die Länge des Slice kürzer als die Länge des Arrays ist, kommt es zur Laufzeitpanik Array ist harmlos und kann normal betrieben werden.
- Darüber hinaus stellt die Spezifikation einige neue Beispiele bereit, die wir in Go1.17 verwenden können:
s := make([]byte, 2, 4) s0 := (*[0]byte)(s) // s0 != nil s2 := (*[2]byte)(s) // &s2[0] == &s[0] s4 := (*[4]byte)(s) // panics: len([4]byte) > len(s) var t []string t0 := (*[0]string)(t) // t0 == nil t1 := (*[1]string)(t) // panics: len([1]string) > len(s)
- Es ist zu beachten, dass es derzeit keine Möglichkeit gibt, zu überprüfen, ob ein Panikereignis aufgrund von außerhalb der Grenzen liegenden Gründen wie der Typzusicherung auftritt. Wenn Sie der Meinung sind, dass Ihr Snippet zu kurz ist und ein Panikereignis auslösen könnte, müssen Sie zur Vorabbestimmung „if“ verwenden.
- Gleichzeitig wird auch die Standardbibliothek Reflect aktualisiert, um die Konvertierung von Slices in Array-Zeiger zu unterstützen. Wenn Sie Reflect für entsprechende Konvertierungsarbeiten verwenden, wird empfohlen, die Hinweise in der Einreichung zu lesen.
Haben Sie weitere Gedanken und Anforderungen
zur Typkonvertierung in der Go-Spracheoder sind Sie auf Fallstricke gestoßen?
Jeder ist herzlich eingeladen, im Kommentarbereich Nachrichten zu hinterlassen und zu kommunizieren.
Weitere technische Artikel zum Thema Golang finden Sie in der Golang