Go-Funktionsargumente werden als Wert übergeben.
Lassen Sie uns zunächst die irrelevanten Teile Ihres Beispiels verwerfen, damit wir leicht erkennen können, dass Sie lediglich ein Argument nach Wert übergeben. Zum Beispiel,
package main
import "fmt"
func byval(q *int) {
fmt.Printf("3. byval -- q %T: &q=%p q=&i=%p *q=i=%v\n", q, &q, q, *q)
*q = 4143
fmt.Printf("4. byval -- q %T: &q=%p q=&i=%p *q=i=%v\n", q, &q, q, *q)
q = nil
}
func main() {
i := int(42)
fmt.Printf("1. main -- i %T: &i=%p i=%v\n", i, &i, i)
p := &i
fmt.Printf("2. main -- p %T: &p=%p p=&i=%p *p=i=%v\n", p, &p, p, *p)
byval(p)
fmt.Printf("5. main -- p %T: &p=%p p=&i=%p *p=i=%v\n", p, &p, p, *p)
fmt.Printf("6. main -- i %T: &i=%p i=%v\n", i, &i, i)
}
Ausgabe:
1. main -- i int: &i=0xf840000040 i=42
2. main -- p *int: &p=0xf8400000f0 p=&i=0xf840000040 *p=i=42
3. byval -- q *int: &q=0xf8400000d8 q=&i=0xf840000040 *q=i=42
4. byval -- q *int: &q=0xf8400000d8 q=&i=0xf840000040 *q=i=4143
5. main -- p *int: &p=0xf8400000f0 p=&i=0xf840000040 *p=i=4143
6. main -- i int: &i=0xf840000040 i=4143
In Funktion main, iist eine intVariable an der Speicherstelle ( &i) 0xf800000040mit einem Anfangswert ( i) 42.
In Funktion main, pist ein Zeiger auf eine intVariable an der Speicherstelle ( &p) 0xf8000000f0mit einem Wert ( p= &i) , 0xf800000040welche Punkte auf einen intWert ( *p= i) 42.
In Funktion main, byval(p)ist ein Funktionsaufruf, der den Wert (teilt p= &i) 0xf800000040des Arguments an der Speicherstelle ( &p) 0xf8000000f0an den byvalFunktionsparameter qan der Speicherstelle ( &q) 0xf8000000d8. Mit anderen Worten, dem byvalParameter wird Speicher zugewiesen , qund der Wert des main byvalArguments pwird ihm zugewiesen. Die Werte von pund qsind anfangs gleich, aber die Variablen pund qsind unterschiedlich.
In der Funktion byvalwird integer ( ) unter Verwendung von pointer q( *int), einer Kopie von pointer p( *int), auf einen neuen int-Wert gesetzt . Am Ende vor der Rückkehr. Der Zeiger wird auf (Nullwert) gesetzt, was keine Auswirkung hat, da es sich um eine Kopie handelt.*qi4143qnilpq
In Funktion main, pist ein Zeiger auf eine intVariable an der Speicherstelle ( &p) 0xf8000000f0mit einem Wert ( p= &i) , 0xf800000040welche Punkte auf einen neuen intWert ( *p= i) 4143.
In Funktion main, iist eine intVariable an der Speicherstelle ( &i) 0xf800000040mit einem Endwert ( i) 4143.
In Ihrem Beispiel die Funktion mainVariable sals Argument an die Funktion gotestAufruf ist nicht das gleiche wie die Funktion gotestParameter s. Sie haben denselben Namen, sind jedoch unterschiedliche Variablen mit unterschiedlichen Bereichen und Speicherorten. Der Funktionsparameter sverbirgt das Funktionsaufrufargument s. Deshalb in meinem Beispiel habe ich die Argumentation und Parametervariablen genannt pund qjeweils die Differenz zu betonen.
In Ihrem Beispiel ( &s) 0x4930d4ist die Adresse des Speicherplatzes für die Variable sin der Funktion , maindie als Argument für den Funktionsaufruf verwendet wird gotest(s, done), und 0x4974d8ist die Adresse des Speicherplatzes für den gotestFunktionsparameter s. Wenn Sie den Parameter s = nilam Ende der Funktion festlegen gotest, hat dies keine Auswirkungen auf die Variable sin main. sin mainund sin gotestsind unterschiedliche Speicherorte. In Bezug auf Typen &sist **Something, sist *Somethingund *sist Something. &sist ein Zeiger auf (Adresse des Speicherorts) s, der ein Zeiger auf (Adresse des Speicherorts) eine anonyme Variable vom Typ istSomething. In Bezug auf die Werte, main.&s != gotest.&s, main.s == gotest.s, main.*s == gotest.*s, und main.s.number == gotest.s.number.
Sie sollten den weisen Rat von mkb befolgen und die Verwendung einstellen println(&s). Verwenden Sie das fmtPaket zum Beispiel,
fmt.Printf("%v %p %v\n", &s, s, *s)
Zeiger haben denselben Wert, wenn sie auf denselben Speicherort zeigen. Zeiger haben unterschiedliche Werte, wenn sie auf unterschiedliche Speicherorte zeigen.