Cet article explique principalement si Go a un passage de paramètres par référence (par rapport au C++). Les amis qui en ont besoin peuvent se référer à
Trois méthodes de passage de paramètres en C++
Passage de valeurs :
La méthode la plus courante de transmission de paramètres. Les paramètres formels d'une fonction sont des copies des paramètres réels. n'affectera pas les paramètres formels en dehors de la fonction. Généralement, le passage de valeur est utilisé lors de la modification de paramètres dans une fonction sans affecter l'appelant.Passage de pointeur
Le paramètre formel est un pointeur vers l'adresse du paramètre réel, comme son nom l'indique, lorsque le contenu pointé par le paramètre formel est manipulé. dans la fonction, le paramètre lui-même sera modifié.Passage par référence
En C++, une référence est un alias pour une variable, qui est en fait la même chose et existe également à la même adresse en mémoire. En d’autres termes, partout où une référence est manipulée, la variable référencée est directement manipulée. Regardez la démo ci-dessous :#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; }
Transfert de valeur, adresse variable : 0x28fe90, valeur variable : 5
Après l'opération de transfert de valeur, valeur variable : 5
Adresse réelle de la variable : 0x28feac, valeur variable : 5
Transfert de pointeur, variable adresse : 0x28feac, valeur variable : 5
Après l'opération de transfert de pointeur, valeur variable : 6
Adresse réelle de la variable : 0x28feac, valeur variable : 6
Transfert de pointeur, adresse variable : 0x28feac, valeur variable : 6
Après l'opération de transfert de référence, Valeur de la variable : 7
Passage des paramètres dans Go
Ce qui précède présente les trois méthodes de passage des paramètres de C++, le passage de valeurs et le passage de pointeurs sont faciles à comprendre, alors Go dispose-t-il également de ces méthodes de passage de paramètres ? Cela a suscité une controverse, mais par rapport au concept de passage de références en C++, on peut dire que Go n'a pas de méthode de passage de références. Pourquoi je dis cela ? Parce que Go n'a pas le concept de références variables. Mais Go a des types de référence, qui seront expliqués plus tard. Regardons d'abord un exemple de transmission de valeurs et de pointeurs dans Go :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) }
L'adresse réelle de la variable : 0xc04203c1d0 Valeur de la variable : 1
Transfert de valeur, adresse de la variable : 0xc04203c210 Valeur de la variable : 2
Après l'opération de transfert de valeur, valeur de la variable : 1
Adresse réelle de la variable : 0xc04203c1d0 Variable valeur : 1
Transfert de pointeur, adresse variable : 0xc04203c1d0 Valeur de la variable : 2
Après l'opération de transfert de pointeur, valeur de variable : 2
On peut voir que le transfert de valeur et le transfert de pointeur des types de base de Go ne sont pas différent du C++, mais il n’a pas de concept de références variables. Alors, comment comprenez-vous les types de référence de Go ?
Types de référence de Go
Dans Go, les types de référence incluent des tranches, des dictionnaires, des canaux, etc. Prenons l'exemple du découpage. Le fait de passer une tranche est-il une référence ? Par exemple :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) }
Dans func1 : [val1]La valeur de m1 après l'appel de func1 : [val1]La modification de la tranche dans la fonction affecte la valeur du paramètre réel. Cela signifie-t-il qu'il s'agit d'un passage par référence ? En fait non. Pour répondre à cette question, il faut d'abord savoir si la fonction appelante slice m1 a changé. Nous devons d’abord comprendre la nature du découpage. Une tranche est une description d'un fragment de tableau. Il contient un pointeur vers le tableau, la longueur du fragment. En d'autres termes, ce que nous imprimons ci-dessus n'est pas la tranche elle-même, mais le tableau pointé par la tranche. Pour un autre exemple, vérifiez si la tranche a changé.
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)) }
Résumé
Le résumé est très simple, et le langage doit aussi voir à travers le phénomène pour en voir l'essence. Il y a aussi la conclusion de cet article qu'il faut retenir : Il n'y a pas de passage par référence dans Go.Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!