Heim >Backend-Entwicklung >Golang >Warum erstellen Go-Slice-Bereichsschleifen beim Zuordnen von Strukturen gemeinsame Adressen?

Warum erstellen Go-Slice-Bereichsschleifen beim Zuordnen von Strukturen gemeinsame Adressen?

Linda Hamilton
Linda HamiltonOriginal
2024-12-04 22:44:11554Durchsuche

Why Do Go Slice Range Loops Create Shared Addresses When Mapping Structs?

Das Go-Slice-Range-Phänomen verstehen

Problem: Das mysteriöse Slice-Range-Verhalten

In Go sind Slices eine leistungsstarke Datenstruktur, die iteriert werden kann über die Verwendung des Schlüsselworts „range“ hinaus. Bei einem besonderen Phänomen kommt es jedoch vor, dass die Elemente in der resultierenden Karte bei der Iteration über ein Segment von Strukturen mithilfe eines For-Bereichs dieselbe Adresse haben. Dieses Verhalten kann verwirrend sein, insbesondere da die Elemente im ursprünglichen Slice eindeutige Adressen haben sollten.

Erklärung: Das Problem lokaler Variablen

Der Schlüssel zum Verständnis dieses Phänomens liegt in der Art und Weise, wie Variablen sind im Speicher abgelegt. Beim Zugriff auf ein Element des Slice innerhalb der for-range-Schleife (in diesem Fall stu) enthält die lokale Variable stu eine Kopie der Struktur. Durch die Zuweisung des Zeigers zur lokalen Variablen werden alle Elemente in der Karte effektiv auf dieselbe Kopie der Struktur im Speicher verwiesen.

Lösung des Problems: Übergeben von Slice-Elementadressen

Um dieses Problem zu beheben und Um die Adressen der Slice-Elemente zuzuweisen, muss der Code geändert werden, um die Adresse des Slice-Elements selbst zu übernehmen. Durch die Verwendung von s[i] anstelle von stu wird der Zeiger auf das tatsächliche Element im Slice der Karte zugewiesen.

Beispiel: Demonstration der Lösung

package main

import "fmt"

type student struct {
    Name string
    Age  int
}

func main() {
    m := make(map[string]*student)
    s := []student{
        {Name: "Allen", Age: 24},
        {Name: "Tom", Age: 23},
    }

    for i := range s {
        m[s[i].Name] = &s[i] // Change here
    }
    fmt.Println(m)
    for key, value := range m {
        fmt.Println(key, value)
    }
}

Ausgabe:

map[Allen:0xc0000a6058 Tom:0xc0000a6060]
Allen &{Allen 24}
Tom &{Tom 23}

Fazit

Durch das Verständnis des zugrunde liegenden Speicherverwaltungsverhaltens können wir dieses Slice-Range-Phänomen in Go angehen. Indem wir die Adresse des Slice-Elements selbst übernehmen, stellen wir sicher, dass jedes Element in der Karte auf eine eindeutige Struktur im Speicher verweist, wodurch die Datenintegrität gewahrt bleibt.

Das obige ist der detaillierte Inhalt vonWarum erstellen Go-Slice-Bereichsschleifen beim Zuordnen von Strukturen gemeinsame Adressen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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