23、Go 函数- 参数的值传递与引用传递

作者: 温新

分类: 【Go基础】

阅读: 674

时间: 2023-08-29 15:54:58

hi,我是温新

Go 语言中,函数参数的传递可以分为 按值传递按引用传递

Go 语言中,默认是按值传递

按值传递:指在调用函数时将实际参数复制一份到函数中*,那么在函数中对参数所进行的修改不会影响到实际参数*。

按引用传递:指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改将会影响实际参数

到这里应该明白,想要函数直接修改参数的值,就需要使用引用传递。

引用传递的语法

引用传递地址,在变量名前加上 & 符号,如此就是引用传递了。此时传递参数的不再是值而是指针(也就是内存地址)。

需要注意的是,如果把指针传递给函数,指针的值就会被复制(指针的值就是内存地址),指针只复制地址而不会复制值。如变量 a,和 变量 b = &a,此时变量 b 的值是变量 a 的内存地址。修改变量 b 指针的值,那么变量 a 的值也就被修改了。

值传递与引用传递案例

package main

import "fmt"

func main() {
    x := 1
    fmt.Println("x =", x, ";函数内存地址为 &x =", &x)

    // 值传递
    y := add(x)
    fmt.Println("x = ", x, "; y = ", y, "; 地址为 &y = ", &y)

    // 引用传递
    // 引用传递通过 & 符号把地址传递给函数
    z := add1(&x)
    fmt.Println("x =", x, "z =", z, "&z =", &z)
}

// 值传递
func add(num int) int {
    // 操作变量副本的值
    num++

    return num
}

// 引用传递
// 函数接收引用传递的地址时,使用 * 取出地址的值
func add1(num *int) int {
    // 操作内存地址的值
    *num++

    return *num
}

输出结果为

x = 1 ;函数内存地址为 &x = 0xc00001a0a8
x = 1 ; y =  2 ; 地址为 &y =  0xc00001a0c8
x = 2 z = 2 &z = 0xc00001a0e0

通过案例可以看到:

1、使用值传递时,变量 x 和 y 的内存地址是一样的,而修改 y 的值时,不会影响到 x 的值;

2、使用引用传递时,变量 x 和 z 的内存地址不一样,而修改 z 的值时,会影响的 x 的值,原因是 指针变量 z 的值存储的是变量 x 的内存地址。

引用传递的优势

1、使得多个函数可以操作同一个对象;

2、传递指针比较轻量级,可以使用指针传递体积大的解构体;在函数调用时 像切片 lic )、 字典( map 接口 interface )、通道( channel )这样的 引用 类型 是默 使用引用传递 的(即使没有显式地指出指针);

3、传递指针给函数不但可以节省内存,还能赋予函数直接修改外部变量的能力,因此被修改的变量不再需要使用 return 返回,案例如下:

package main

import "fmt"

func main() {
    num := 0
    result := &num
    noReturn(2, 2, result)
    fmt.Println("结果: ", *result)
}

func noReturn(m, n int, res *int) {
    *res = m * n
}
请登录后再评论