In diesem Artikel wird hauptsächlich erläutert, ob Go über Parameterübergabe per Referenz verfügt (im Vergleich zu C++). Freunde, die dies benötigen, können sich auf
Drei Parameterübergabemethoden in C++
Wertübergabe:
Die gebräuchlichste Methode zur Parameterübergabe sind Kopien der tatsächlichen Parameter in der Funktion hat keinen Einfluss auf formale Parameter außerhalb der Funktion. Im Allgemeinen wird die Wertübergabe verwendet, wenn Parameter innerhalb einer Funktion geändert werden, ohne dass sich dies auf den Aufrufer auswirkt.Zeigerübergabe
Der formale Parameter ist ein Zeiger auf die Adresse des tatsächlichen Parameters, wenn der Inhalt, auf den der formale Parameter zeigt, manipuliert wird In der Funktion wird der eigentliche Parameter selbst geändert.Übergabe als Referenz
In C++ ist eine Referenz ein Alias für eine Variable, die eigentlich dasselbe ist und auch an derselben Adresse im Speicher existiert. Mit anderen Worten: Wo immer eine Referenz manipuliert wird, wird die referenzierte Variable ganz direkt manipuliert. Sehen Sie sich die Demo unten an:#include <iostream> //值传递 void func1(int a) { std::cout << "值传递,变量地址:" << &a << ", 变量值:" << a << std::endl; a ++ ; } //指针传递 void func2 (int* a) { std::cout << "指针传递,变量地址:" << a << ", 变量值:" << *a << std::endl; *a = *a + 1; } //引用传递 void func3 (int& a) { std::cout << "指针传递,变量地址:" << &a << ", 变量值:" << a << std::endl; a ++; } int main() { int a = 5; std::cout << "变量实际地址:" << &a << ", 变量值:" << a << std::endl; func1(a); std::cout << "值传递操作后,变量值:" << a << std::endl; std::cout << "变量实际地址:" << &a << ", 变量值:" << a << std::endl; func2(&a); std::cout << "指针传递操作后,变量值:" << a << std::endl; std::cout << "变量实际地址:" << &a << ", 变量值:" << a << std::endl; func3(a); std::cout << "引用传递操作后,变量值:" << a << std::endl; return 0; }
Wertübertragung, Variablenadresse: 0x28fe90, Variablenwert: 5
Nach dem Wertübertragungsvorgang, Variablenwert: 5
Aktuelle Variablenadresse: 0x28feac, Variablenwert: 5
Zeigerübertragung, Variable Adresse: 0x28feac, Variablenwert: 5
Nach der Zeigerübertragungsoperation, Variablenwert: 6
Aktuelle Variablenadresse: 0x28feac, Variablenwert: 6
Zeigerübertragung, Variablenadresse: 0x28feac, Variablenwert: 6
Nach der Referenzübertragungsoperation,Variablenwert: 7
Parameterübergabe in Go
Das Obige stellt die drei Parameterübergabemethoden von vor C++, Wertübergabe und Zeigerübergabe sind leicht zu verstehen. Verfügt Go also auch über diese Methoden zur Parameterübergabe? Dies hat zu Kontroversen geführt, aber im Vergleich zum Konzept der Referenzübergabe in C++ können wir sagen, dass Go über keine Methode zur Referenzübergabe verfügt. Warum sage ich das? Weil Go das Konzept der Variablenreferenzen nicht hat. Go verfügt jedoch über Referenztypen, die später erläutert werden. Sehen wir uns zunächst ein Beispiel für die Übergabe von Werten und Zeigern in Go an:package main import ( "fmt" ) func main() { a := 1 fmt.Println( "变量实际地址:", &a, "变量值:", a) func1 (a) fmt.Println( "值传递操作后,变量值:", a) fmt.Println( "变量实际地址:", &a, "变量值:", a) func2(&a) fmt.Println( "指针传递操作后,变量值:", a) } //值传递 func func1 (a int) { a++ fmt.Println( "值传递,变量地址:", &a, "变量值:", a) } //指针传递 func func2 (a *int) { *a = *a + 1 fmt.Println( "指针传递,变量地址:", a, "变量值:", *a) }
Die tatsächliche Adresse der Variablen: 0xc04203c1d0 Variablenwert: 1
Wertübertragung, Variablenadresse: 0xc04203c210 Variablenwert: 2
Nach dem Wertübertragungsvorgang Variablenwert: 1
Aktuelle Variablenadresse: 0xc04203c1d0 Variable Wert: 1
Zeigerübertragung, Variablenadresse: 0xc04203c1d0 Variablenwert: 2
Nach der Zeigerübertragungsoperation Variablenwert: 2
Es ist ersichtlich, dass die Wertübertragung und Zeigerübertragung der Grundtypen von Go nein sind unterscheidet sich von C++, verfügt jedoch über kein Variablenreferenzkonzept. Wie verstehen Sie also die Referenztypen von Go?
Gos Referenztypen
In Go umfassen Referenztypen Slices, Wörterbücher, Kanäle usw. Nehmen Sie als Beispiel das Slicing. Ist die Übergabe eines Slice eine Referenz? Zum Beispiel:package main import ( "fmt" ) func main() { m1 := make([]string, 1) m1[0] = "test" fmt.Println("调用 func1 前 m1 值:", m1) func1(m1) fmt.Println("调用 func1 后 m1 值:", m1) } func func1 (a []string) { a[0] = "val1" fmt.Println("func1中:", a) }
In func1: [val1]Der Wert von m1 nach dem Aufruf von func1: [val1]Die Änderung am Slice in der Funktion wirkt sich auf den Wert des tatsächlichen Parameters aus. Bedeutet das, dass es sich hierbei um eine Referenzübergabe handelt? Eigentlich nicht. Um diese Frage zu beantworten, müssen wir zunächst herausfinden, ob sich die aufrufende Funktionsscheibe m1 geändert hat. Zuerst müssen wir die Natur des Schneidens verstehen. Ein Slice ist eine Beschreibung eines Array-Fragments. Es enthält einen Zeiger auf das Array, die Länge des Fragments. Mit anderen Worten, was wir oben drucken, ist nicht das Slice selbst, sondern das Array, auf das das Slice zeigt. Überprüfen Sie in einem anderen Beispiel, ob sich das Slice geändert hat.
package main import ( "fmt" ) func main() { m1 := make([]string, 1) m1[0] = "test" fmt.Println("调用 func1 前 m1 值:", m1, cap(m1)) func1(m1) fmt.Println("调用 func1 后 m1 值:", m1, cap(m1)) } func func1 (a []string) { a = append(a, "val1") fmt.Println("func1中:", a, cap(a)) }
Zusammenfassung
Die Zusammenfassung ist sehr einfach, und die Sprache muss auch das Phänomen durchschauen, um das Wesentliche zu erkennen. Es gibt auch die Schlussfolgerung dieses Artikels, an die man sich erinnern muss: In Go gibt es keine Pass-by-Referenz.Das obige ist der detaillierte Inhalt vonGo-Sprachvergleich C++-Referenzparameterübergabe. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!