Unerwartetes Verhalten bei Anhängevorgängen für Slices
In Go kann unerwartetes Verhalten auftreten, wenn Elemente während Schleifeniterationen an Slices angehängt und dann neue erstellt werden Slices basierend auf den Ergebnissen. Dieses Verhalten ist auf das zugrunde liegende Array zurückzuführen, das die Referenz aufteilt.
Betrachten Sie den folgenden Code:
<code class="go">func create(iterations int) []int { a := make([]int, 0) for i := 0; i < iterations; i++ { a = append(a, i) } return a }</code>
Wenn wir create(11) aufrufen und das Ergebnis i zuweisen, erwarten wir jedes nachfolgende Anhängen Operation (j := append(i, 100), g := append(i, 101) und h := append(i, 102)), um neue Slices mit unterschiedlichen Werten zu erstellen. Das beobachtete Verhalten besteht jedoch darin, dass das letzte Element dieser neuen Slices immer 102 ist, unabhängig von ihrem Index.
Dies geschieht, weil alle Anhänge das gleiche zugrunde liegende Array ändern. Das Anhängen eines Elements an das Slice ändert die Länge und kann zu einer Neuzuweisung des Arrays führen. Wenn ein neues Array zugewiesen wird, werden alle vorherigen Verweise auf das alte Array ungültig.
Slice-Literale verhalten sich jedoch wie erwartet, da immer dann ein neues Array zugewiesen wird, wenn das Anhängen die Kapazität des Hintergrundarrays überschreiten würde.
Idiomatischer Ansatz
Um ein vorhersehbares Verhalten beim Erstellen mehrerer neuer Slices basierend auf einem vorhandenen Slice sicherzustellen, besteht der idiomatische Ansatz darin, das Slice zu kopieren, bevor Elemente angehängt werden:
<code class="go">func makeFromSlice(sl []int) []int { result := make([]int, len(sl)) copy(result, sl) return result }</code>
Durch das Durchführen einer Kopie erstellen wir ein neues Backing-Array und stellen sicher, dass Änderungen, die am resultierenden Slice vorgenommen werden, keine Auswirkungen auf das ursprüngliche Slice haben.
Das obige ist der detaillierte Inhalt vonWarum führt das Anhängen an ein Slice in einer Schleife zu unerwarteten Ergebnissen in Go?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!