• 内存地址

    在Go语言中,可以使用&符来表示一个变量在内存中的地址。比如

    package main
    import "fmt"
    func main() {
       var a int = 10
       fmt.Printf("Address of a variable: %x\n", &a  )
    }
    

    执行上面的代码,就会输出变量 a 的内存地址

    Address of a variable: c042052058
    

    指针

    指针是一个指向变量在内存中实际地址的对象。和其它变量一样,要先声明一个指针变量才能使用。

    声明一个指针变量:

    var var-name *var-type
    
    • var-type 是指针的基类型,它必须是Go的数据类型,例如 int , float32
    • var-name 是指针变量的名称

    使用指针

    可以在指针变量前加 * 输出其所存储的变量的值

    package main
    import "fmt"
    func main() {
       var a int= 20   /* 声明实际变量 */
       var ip *int        /* 声明指针变量 */
       ip = &a  /* 将实际变量的存储地址赋给指针变量 */
       fmt.Printf("a 变量的地址是: %x\n", &a  )
       /* 指针变量存储的指针地址 */
       fmt.Printf("ip 变量储存的指针地址: %x\n", ip )
       /* 使用指针访问值 */
       fmt.Printf("*ip 变量的值: %d\n", *ip )
    }
    

    上面的代码执行的结果是:

    a 变量的地址是: 20818a220
    ip 变量储存的指针地址: 20818a220
    *ip 变量的值: 20
    

    nil指针

    nil 是未分配地址的指针变量的值。
    值为 nil 的指针变量被称为 nil 指针。

    package main
    import "fmt"
    func main() {
       var  ptr *int
       fmt.Printf("The value of ptr is : %x\n", ptr  )
    }
    

    上面的代码执行的结果是:

    The value of ptr is 0
    

    同时,可以使用 ptr == nil 来判断一个指针变量是否为 nil 指针。

    引用传递

    Go 语言允许向函数传递指针,只需要在函数定义的参数上设置为指针类型即可。向这种函数传递参数称为引用传递,引用传递在函数中进行的修改将影响到实际参数。

    package main
    import "fmt"
    func main() {
       /* 定义局部变量 */
       var a int = 100
       var b int= 200
       fmt.Printf("交换前 a 的值 : %d\n", a )
       fmt.Printf("交换前 b 的值 : %d\n", b )
       /* 调用函数用于交换值
       * &a 指向 a 变量的地址
       * &b 指向 b 变量的地址
       */
       swap(&a, &b);
       fmt.Printf("交换后 a 的值 : %d\n", a )
       fmt.Printf("交换后 b 的值 : %d\n", b )
    }
    func swap(x *int, y *int) {
       var temp int
       temp = *x    /* 保存 x 地址的值 */
       *x = *y      /* 将 y 赋值给 x */
       *y = temp    /* 将 temp 赋值给 y */
    }```
    以上实例允许输出结果为:
    ```go
    交换前 a 的值 : 100
    交换前 b 的值 : 200
    交换后 a 的值 : 200
    交换后 b 的值 : 100