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
, i
ist eine int
Variable an der Speicherstelle ( &i
) 0xf800000040
mit einem Anfangswert ( i
) 42
.
In Funktion main
, p
ist ein Zeiger auf eine int
Variable an der Speicherstelle ( &p
) 0xf8000000f0
mit einem Wert ( p
= &i
) , 0xf800000040
welche Punkte auf einen int
Wert ( *p
= i
) 42
.
In Funktion main
, byval(p)
ist ein Funktionsaufruf, der den Wert (teilt p
= &i
) 0xf800000040
des Arguments an der Speicherstelle ( &p
) 0xf8000000f0
an den byval
Funktionsparameter q
an der Speicherstelle ( &q
) 0xf8000000d8
. Mit anderen Worten, dem byval
Parameter wird Speicher zugewiesen , q
und der Wert des main
byval
Arguments p
wird ihm zugewiesen. Die Werte von p
und q
sind anfangs gleich, aber die Variablen p
und q
sind unterschiedlich.
In der Funktion byval
wird 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.*q
i
4143
q
nil
p
q
In Funktion main
, p
ist ein Zeiger auf eine int
Variable an der Speicherstelle ( &p
) 0xf8000000f0
mit einem Wert ( p
= &i
) , 0xf800000040
welche Punkte auf einen neuen int
Wert ( *p
= i
) 4143
.
In Funktion main
, i
ist eine int
Variable an der Speicherstelle ( &i
) 0xf800000040
mit einem Endwert ( i
) 4143
.
In Ihrem Beispiel die Funktion main
Variable s
als Argument an die Funktion gotest
Aufruf ist nicht das gleiche wie die Funktion gotest
Parameter s
. Sie haben denselben Namen, sind jedoch unterschiedliche Variablen mit unterschiedlichen Bereichen und Speicherorten. Der Funktionsparameter s
verbirgt das Funktionsaufrufargument s
. Deshalb in meinem Beispiel habe ich die Argumentation und Parametervariablen genannt p
und q
jeweils die Differenz zu betonen.
In Ihrem Beispiel ( &s
) 0x4930d4
ist die Adresse des Speicherplatzes für die Variable s
in der Funktion , main
die als Argument für den Funktionsaufruf verwendet wird gotest(s, done)
, und 0x4974d8
ist die Adresse des Speicherplatzes für den gotest
Funktionsparameter s
. Wenn Sie den Parameter s = nil
am Ende der Funktion festlegen gotest
, hat dies keine Auswirkungen auf die Variable s
in main
. s
in main
und s
in gotest
sind unterschiedliche Speicherorte. In Bezug auf Typen &s
ist **Something
, s
ist *Something
und *s
ist Something
. &s
ist 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 fmt
Paket 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.