← 返回首页
Go基础教程(九)
发表时间:2022-11-12 22:36:14
指针

指针就是保存内存地址的变量。

1.指针

和C语言类似,Go语言也有指针的概念,在 Go 语言中, 指针包括两个核心概念:

与C语言类似,Go 语言中也是通过 & 操作符对变量进行 "取地址" 操作,格式如下:

package main

import "fmt"

func main() {
    // 声明一个整型的 man 变量
    var man int = 100
    // 声明一个字符串类型 domain 变量
    var domain string = "www.simoniu.com"
    p1 := &man
    p2 := &domain
    // 通过 %p 输出 man 和 domain 变量取地址后的指针值,指针值带有 0x 的十六进制前缀
    fmt.Printf("%p %p", p1, p2)
}

运行结果:

0xc0000a6058 0xc000088220

总结: 变量、指针和地址三者的关系是:每个变量都拥有地址,指针的值表示这个地址。

2.获取指针指向的值

与C语言类似,*,取值操作符,功能是取出地址指向的实际值。

package main

import "fmt"

func main() {
    // 声明一个整型的 man 变量
    var man int = 100
    // 声明一个字符串类型 domain 变量
    var domain string = "www.simoniu.com"
    p1 := &man
    p2 := &domain
    // 通过 %p 输出 man 和 domain 变量取地址后的指针值,指针值带有 0x 的十六进制前缀
    fmt.Printf("%p, %p\n", p1, p2)

    value1 := *p1
    value2 := *p2

    fmt.Printf("%d, %s\n", value1, value2)

}

运行结果:

0xc0000a6058, 0xc000088220
100, www.simoniu.com 

3.使用指针修改值

使用指针实现两个整数变量的交换。

package main

import "fmt"

// 数值交换函数
func swap(x, y *int) {
    // 取 x 指针的值,赋给临时变量 temp
    temp := *x
    // 取 y 指针的值,赋给 x 指针指向的变量
    *x = *y
    // 将 temp 指针的值赋给 y 指针指向的变量
    *y = temp
}

func main() {
    // 声明两个变量 x, y, 值分别为 1,2
    x, y := 10, 7
    fmt.Println("交换之前, x=", x, " y=", y)
    // 交换变量值
    swap(&x, &y)
    // 输出交换后的 x, y 值
    fmt.Println("交换之后, x=", x, " y=", y)
}

运行结果:

交换之前, x= 10  y= 7
交换之后, x= 7  y= 10 

假设,我们在上面 swap() 函数中交换的是指针值,情况会如何呢?

package main

import "fmt"

// 数值交换函数
func swap(x, y *int) {
    x, y = y, x
}

func main() {
    // 声明两个变量 x, y, 值分别为 1,2
    x, y := 10, 7
    fmt.Println("交换之前, x=", x, " y=", y)
    // 交换变量值
    swap(&x, &y)
    // 输出交换后的 x, y 值
    fmt.Println("交换之后, x=", x, " y=", y)
}

可以看到,值交换失败了。上面 swap() 函数交换的是 x 和 y 的地址,交换完毕后,它们实际指向的值并没有发生改变。

4.通过 new() 函数来创建指针

Go 语言中还提供了 new() 函数来创建指针,格式如下:

package main

import "fmt"

func main() {
    // 声明一个整型的 man 变量
    var man int = 100
    // 声明一个字符串类型 domain 变量
    var domain string = "www.simoniu.com"

    p1 := new(int)
    p2 := new(string)

    p1 = &man
    p2 = &domain
    // 通过 %p 输出 man 和 domain 变量取地址后的指针值,指针值带有 0x 的十六进制前缀
    fmt.Printf("%p, %p\n", p1, p2)

    value1 := *p1
    value2 := *p2

    fmt.Printf("%d, %s\n", value1, value2)
}

运行结果:

0xc00001c098, 0xc000052250
100, www.simoniu.com 

小结:

变量、指针地址、指针变量、取地址、取值的相互关系和特性如下: