Heim > Backend-Entwicklung > Golang > Warum führt das Anhängen von Zeigern in der Append-Funktion von Go zu unerwartetem Überschreiben?

Warum führt das Anhängen von Zeigern in der Append-Funktion von Go zu unerwartetem Überschreiben?

Barbara Streisand
Freigeben: 2024-12-25 03:36:17
Original
744 Leute haben es durchsucht

Why Does Appending Pointers in Go's `append` Function Lead to Unexpected Overwriting?

Unerwartetes Überschreibproblem mit der „Append“-Funktion von Go

In Go wird die Append-Funktion häufig verwendet, um Slices mit zusätzlichen Elementen zu erweitern. Allerdings kann es gelegentlich zu unerwartetem Verhalten kommen, wenn Zeiger an Strukturen angehängt werden.

Bedenken Sie den folgenden Codeausschnitt:

import "fmt"

type Foo struct {
    val int
}

func main() {
    var a = make([]*Foo, 1)
    a[0] = &Foo{0}

    var b = [3]Foo{Foo{1}, Foo{2}, Foo{3}}
    for _, e := range b {
        a = append(a, &e)
    }

    for _, e := range a {
        fmt.Printf("%v ", *e)
    }
}
Nach dem Login kopieren

Interessanterweise wird statt {0} {1} {2} { 3}, der Code gibt {0} {3} {3} {3} aus. Dieses unerwartete Verhalten ist auf einen grundlegenden Aspekt des Verhaltens von Go zurückzuführen:

Kopiert in for-Range-Schleifen

Go iteriert über Slices und Arrays mithilfe von for-Range-Schleifen, die eine Kopie erstellen jedes Elements während der Iteration. In unserem Code stellt die for-Range-Schleifenvariable e eine temporäre Kopie des Array-Elements b[i] dar. Leider hängen wir dann die Adresse dieser temporären Variablen an den Slice a an.

Der Fix

Um dieses Problem zu beheben, müssen wir die Adresse des anhängen ursprüngliches Array-Element anstelle der temporären Kopie. Indem wir die for-Schleife so ändern, dass sie den Index i verwendet, stellen wir sicher, dass die richtige Adresse an das Slice angehängt wird:

for i := range b {
    a = append(a, &b[i])
}
Nach dem Login kopieren

Diese Änderung ergibt die erwartete Ausgabe von {0} {1} {2} {3 }.

Grund für das Verhalten

Gos Mangel an wahren Referenzen trägt zu diesem Verhalten bei. In C oder Java, wo Referenzen verwendet werden, würde die Schleifenvariable direkt auf das Array-Element verweisen und so Mutationen über die Schleifenvariable ermöglichen. In Go ist die Schleifenvariable jedoch eine eindeutige Variable, die eine Kopie des Elements und keine Referenz enthält. Folglich werden an der Schleifenvariablen vorgenommene Änderungen nicht in den ursprünglichen Array-Elementen widergespiegelt.

Das obige ist der detaillierte Inhalt vonWarum führt das Anhängen von Zeigern in der Append-Funktion von Go zu unerwartetem Überschreiben?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage