教程 > Go 教程 > Go 基础 阅读:315

Go 语言指针详解

我们将学习指针在 Go 中的工作原理,我们还将了解 Go 指针与其他语言(如 C 和 C++)中的指针有何不同。

Go 中的指针学习起来既简单又有趣。一些 Go 编程任务使用指针更容易执行,而其他任务,例如按引用调用,如果不使用指针则无法执行。


什么是指针?

简单来说指针是存储另一个变量的内存地址的变量。在 Go 语言变量 一节,我们说过,每个变量都是一个内存位置,每个内存位置都有定义的地址。

Go 指针示意图

在上图中,变量 b 具有值252并存储在内存地址 0x1040a124。变量 a 保存 b 的地址。现在 a 指向 b。

声明指针

*T 是指针变量指向数据类型为T的值。

让我们编写一个声明指针的程序。

package main

import (  
    "fmt"
)

func main() {  
    b := 255
    var a *int = &b
    fmt.Printf("a 的类型为:%T\n", a)
    fmt.Println("b的地址为:", a)
}

上述程序我们将 b 的地址分配给类型时 *int 的变量a。现在说 a 指向 b。当我们打印 a 中的值时,将会显示 b 的地址。上述代码编译执行结果如下

a 的类型为:*int
b的地址为: 0xc000134008

提醒 - 在实际运行中, b 的地址会显示不同的值,因为 b 的位置可以在内存中的任何位置。


指针的零值

指针的零值是Nil。Go 编译器为指针变量分配一个 Nil 值,以防你没有要分配的确切地址。这是在变量声明时完成的。分配为Nil 的指针称为 Nil指针

nil 指针是一个常量,其值为零。

package main

import (  
    "fmt"
)

func main() {  
    a := 25
    var b *int
    if b == nil {
        fmt.Println("b 的值:", b)
        b = &a
        fmt.Println("b 初始化之后:", b)
    }
}

b 在上面的程序中最初为 nil,然后将 a 的地址分配给它。 代码执行结果如下

b 的值: <nil>
b 初始化之后: 0xc000016070

在大多数操作系统上,不允许程序访问地址 0 处的内存,因为该内存是由操作系统保留的。但是,内存地址 0 具有特殊的意义;它表示指针不打算指向可访问的内存位置。但是按照惯例,如果指针包含 nil(零)值,则假定它不指向任何内容。 可以使用以下方式检查 nil 指针

if(ptr != nil)
if(ptr == nil)

使用 new() 函数创建指针

Go 还提供了一个方便的函数 new() 来创建指针。new()函数将一个类型作为参数,并返回一个指向作为参数传递的类型的新分配的零值的指针。

package main

import (  
    "fmt"
)

func main() {  
    size := new(int)
    fmt.Printf("size的值: %d, 类型: %T, 地址: %v\n", *size, size, size)
    *size = 85
    fmt.Println("修改之后的size的值:", *size)
}

运行示例

上述代码执行结果如下

size的值: 0, 类型: *int, 地址: 0xc000016070
修改之后的size的值: 85

访问指针变量

如何访问指针指向的变量的值?需要在变量前面加上星号 *。 例如:*a 是访问a指向的值。

package main  
import (  
    "fmt"
)

func main() {  
    b := 255
    a := &b
    fmt.Println("b 的地址是:", a)
    fmt.Println("b 的值是:", *a)
}

运行示例

上述代码编译执行结果如下

b 的地址是: 0xc000016070
b 的值是: 255

让我们再编写一个程序,b使用指针更改值。

package main

import (
    "fmt"
)

func main() {
    b := 255
    a := &b
    fmt.Println("b 的地址是:", a)
    fmt.Println("b 的值是:", *a)
    *a++
    fmt.Println("修改后 b 的值是:", b)
}

上述代码编译执行结果如下

b 的地址是: 0xc000016070
b 的值是: 255
修改后 b 的值是: 256

Go 不支持指针运算

Go 不支持其他语言(如 C 和 C++)中存在的指针运算。

package main

func main() {  
    b := [...]int{109, 110, 111}
    p := &b
    p++
}

上面的程序会抛出编译错误

study.go:6:3: invalid operation: p++ (non-numeric type *[3]int)

查看笔记

扫码一下
查看教程更方便