Heim > Backend-Entwicklung > Golang > Der Unterschied zwischen Zeigern und Werten auf Methoden

Der Unterschied zwischen Zeigern und Werten auf Methoden

Linda Hamilton
Freigeben: 2024-11-26 01:35:15
Original
370 Leute haben es durchsucht

The difference between pointers and values on methods

Beim Schreiben von Methoden in Go ist eine der wichtigsten Entscheidungen, ob eine Struktur als Wert oder als Zeiger übergeben werden soll. Diese Wahl kann sich auf die Leistung, das Codeverhalten und die Speicherzuweisung auswirken. In diesem Beitrag werden wir diesen Unterschied anhand eines praktischen Beispiels untersuchen und verstehen, wann jeder Ansatz angemessener ist.

Beginnen wir mit einer kleinen Struktur und zwei Methoden: einer, bei der die Struktur als Wert übergeben wird, und einer anderen als Zeiger.

package main

import (
    "fmt"
)

type Person struct {
    Name string
    Age  int
}

// Method with struct passed by value
func (p Person) CelebrateBirthdayValue() {
    p.Age++
}

// Method with struct passed by pointer
func (p *Person) CelebrateBirthdayPointer() {
    p.Age++
}

func main() {
    person := Person{Name: "Alice", Age: 30}

    // Passing by value
    person.CelebrateBirthdayValue()
    fmt.Println("After CelebrateBirthdayValue:", person.Age) // Output: 30

    // Passing by pointer
    person.CelebrateBirthdayPointer()
    fmt.Println("After CelebrateBirthdayPointer:", person.Age) // Output: 31
}
Nach dem Login kopieren
Nach dem Login kopieren

Unterschied zwischen Wert und Zeiger

Wenn wir eine Struktur als Wert an eine Methode übergeben, erstellt Go eine Kopie der Struktur. Alle an der Struktur innerhalb der Methode vorgenommenen Änderungen wirken sich nicht auf die ursprüngliche Struktur aus, da wir mit einer unabhängigen Kopie arbeiten.

Wenn wir andererseits eine Struktur per Zeiger übergeben, übergeben wir die Speicheradresse der ursprünglichen Struktur. Das bedeutet, dass alle Änderungen, die an der Struktur innerhalb der Methode vorgenommen werden, direkt die ursprüngliche Struktur ändern, da wir dieselbe Instanz bearbeiten.

Zusammengefasst:

  • Nach Wert: Die Methode empfängt eine Kopie der Struktur und erstellt so einen neuen Speicherplatz.

  • Durch Zeiger: Die Methode empfängt die Speicheradresse der ursprünglichen Struktur und zeigt auf denselben Speicherplatz.

Haufen

Wenn eine Struktur als Wert übergeben wird, wird die Kopie auf dem Stapel zugewiesen, was im Allgemeinen schnell und effizient ist. Wenn die Struktur jedoch groß ist, kann die Kopie erheblichen Stapelspeicher verbrauchen.

Wenn eine Struktur per Zeiger übergeben wird, wird der Zeiger selbst auf dem Stapel zugewiesen, aber die ursprüngliche Struktur wird möglicherweise auf dem Heap zugewiesen, insbesondere wenn sie mit new, make erstellt oder von einer anonymen Funktion erfasst wurde.

Heap-Zuweisung ist im Hinblick auf Zuweisungszeit und Speicherbereinigung teurer, ermöglicht aber die effiziente Bearbeitung großer Datenmengen, ohne die gesamte Struktur zu kopieren.

Wann Sie die einzelnen Ansätze verwenden sollten

Nach Wert

Die Übergabe von Strukturen nach Wert ist nützlich, wenn:

  • Sie möchten sicherstellen, dass die ursprüngliche Struktur nicht geändert wird.
  • Die Struktur ist klein und das Kopieren hat keinen wesentlichen Einfluss auf die Leistung.
  • Die Methode liest einfach Daten, ohne dass der interne Status geändert werden muss.

Beispiel:

func (p Person) GetName() string {
    return p.Name
}
Nach dem Login kopieren

Hier liest GetName nur das Feld Name und gibt eine Zeichenfolge zurück, ohne den Status der Struktur zu ändern.

Per Zeiger

Die Übergabe von Strukturen per Zeiger ist in folgenden Fällen von Vorteil:

  • Sie müssen die ursprüngliche Struktur ändern.
  • Die Struktur ist groß und das Kopieren ihrer Daten wäre in Bezug auf Speicher und Leistung kostspielig.
  • Sie möchten unnötige Kopien vermeiden, um die Codeeffizienz zu verbessern.

Beispiel:

package main

import (
    "fmt"
)

type Person struct {
    Name string
    Age  int
}

// Method with struct passed by value
func (p Person) CelebrateBirthdayValue() {
    p.Age++
}

// Method with struct passed by pointer
func (p *Person) CelebrateBirthdayPointer() {
    p.Age++
}

func main() {
    person := Person{Name: "Alice", Age: 30}

    // Passing by value
    person.CelebrateBirthdayValue()
    fmt.Println("After CelebrateBirthdayValue:", person.Age) // Output: 30

    // Passing by pointer
    person.CelebrateBirthdayPointer()
    fmt.Println("After CelebrateBirthdayPointer:", person.Age) // Output: 31
}
Nach dem Login kopieren
Nach dem Login kopieren

In diesem Fall ändert UpdateName direkt das Feld Name der ursprünglichen Struktur, was effizienter ist als das Erstellen einer Kopie.

Abschluss

Die Entscheidung, ob beim Schreiben von Methoden in Go eine Struktur als Wert oder als Zeiger übergeben werden soll, ist eine wichtige Entscheidung, die sich auf Leistung, Codeverhalten und Speicherzuweisung auswirken kann.

Die Übergabe von Werten ist nützlich, um die Unveränderlichkeit der Struktur innerhalb der Methode sicherzustellen, während die Übergabe von Zeigern für die Änderung der ursprünglichen Struktur und die Optimierung der Leistung bei der Arbeit mit größeren Strukturen unerlässlich ist.

Das obige ist der detaillierte Inhalt vonDer Unterschied zwischen Zeigern und Werten auf Methoden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
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