Heim  >  Artikel  >  Backend-Entwicklung  >  ## Warum kann ich in Go eine Zeigermethode für einen Wert aufrufen?

## Warum kann ich in Go eine Zeigermethode für einen Wert aufrufen?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-10-25 07:55:02770Durchsuche

##  Why Can I Call a Pointer Method on a Value in Go?

Empfängermethoden rufen Syntaxverwirrung in Go auf

Bei der Untersuchung der Unterschiede zwischen Zeigern und Werten für Empfänger wird darauf hingewiesen, dass Wertmethoden auftreten können werden sowohl für Zeiger als auch für Werte aufgerufen, während Zeigermethoden nur auf Zeiger beschränkt sind. Diese Einschränkung ergibt sich aus der Fähigkeit von Zeigermethoden, den Empfänger zu ändern, was dazu führt, dass Änderungen verworfen werden, wenn sie für eine Kopie des Werts aufgerufen werden.

Ein Codebeispiel, das zeigt, wie eine Zeigermethode für einen Wert aufgerufen wird, sorgt jedoch für Verwirrung. Der Code lautet wie folgt:

<code class="go">package main

import (
    "fmt"
    "reflect"
)

type age int

func (a age) String() string {
    return fmt.Sprintf("%d year(s) old", int(a))
}

func (a *age) Set(newAge int) {
    if newAge >= 0 {
        *a = age(newAge)
    }
}

func main() {
    var vAge age = 5
    pAge := new(age)

    fmt.Printf("Type information:\n\tvAge: %v\n\tpAge: %v\n", reflect.TypeOf(vAge),
        reflect.TypeOf(pAge))

    fmt.Printf("vAge.String(): %v\n", vAge.String())
    fmt.Printf("vAge.Set(10)\n")
    vAge.Set(10)
    fmt.Printf("vAge.String(): %v\n", vAge.String())

    fmt.Printf("pAge.String(): %v\n", pAge.String())
    fmt.Printf("pAge.Set(10)\n")
    pAge.Set(10)
    fmt.Printf("pAge.String(): %v\n", pAge.String())
}</code>

Obwohl in der Dokumentation angegeben ist, dass dies nicht möglich sein sollte, lässt sich dieser Code ohne Fehler kompilieren und ausführen. Was verursacht also diese scheinbare Inkonsistenz?

Die Antwort liegt im Konzept der adressierbaren Werte. Die Go-Spezifikation definiert: „Ein Methodenaufruf x.m() ist gültig, wenn der Methodensatz von (der Typ von) x m enthält und die Argumentliste der Parameterliste von m zugewiesen werden kann.“ Zusätzlich: „Wenn x adressierbar ist und der Methodensatz von &x m enthält, ist x.m() die Abkürzung für (&x).m().“

In diesem Fall ist vAge adressierbar, was bedeutet, dass es eine gültige Speicheradresse hat . Beim Aufruf von vAge.Set() erkennt der Compiler, dass die Zeigerempfängermethode Set() auch über die Adresse des Werts aufgerufen werden kann, was äquivalent zu (&vAge).Set().

ist

Das obige ist der detaillierte Inhalt von## Warum kann ich in Go eine Zeigermethode für einen Wert aufrufen?. 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