手册教程~

Go - 指针

Go 语言中指针是很容易学习的,Go 语言中使用指针可以更简单的执行一些任务。

接下来让我们来一步步学习 Go 语言指针。

我们都知道,变量是一种使用方便的占位符,用于引用计算机内存地址。

Go 语言的取地址符是 &,放到一个变量前使用就会返回相应变量的内存地址。

以下实例演示了变量在内存中地址:

package main

import "fmt"

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

当上面的代码被编译和执行时,它产生结果如下:

Address of a variable: 10328000

现在我们已经了解了什么是内存地址和如何去访问它。接下来我们将具体介绍指针。

什么是指针?

一个指针变量指向了一个值的内存地址。

类似于变量和常量,在使用指针前你需要声明指针。指针声明格式如下:

var var_name *var-type

这里,var-type是指针的基类型; 它必须是有效的Go数据类型,var-name是指针变量的名称。用于声明指针的星号(*)与用于乘法的星号相同。但是,在此语句中,星号(*)用于将变量指定为指针。

以下是有效的指针声明:

var ip *int        /* pointer to an integer */
var fp *float32    /* pointer to a float */

所有指针的值的实际数据类型(无论是整数,浮点数还是其他数据类型)都是相同的,它表示内存地址的长十六进制数。不同数据类型的指针的唯一区别是指针所指向的是变量或常量的数据类型。

如何使用指针?

有几个重要的操作,将非常频繁地使用指针来实现。

定义一个指针变量将一个变量的地址赋值给一个指针 最后访问指针变量中可用地址的值

这是通过使用一元运算符*来返回位于操作数指定的地址的变量的值。下面的例子使用这些操作:

package main

import "fmt"

func main() {
   var a int = 20   /* actual variable declaration */
   var ip *int      /* pointer variable declaration */

   ip = &a  /* store address of a in pointer variable*/

   fmt.Printf("Address of a variable: %x\n", &a  )

   /* address stored in pointer variable */
   fmt.Printf("Address stored in ip variable: %x\n", ip )

   /* access the value using the pointer */
   fmt.Printf("Value of *ip variable: %d\n", *ip )
}

当上面的代码编译和执行时,它产生结果如下:

Address of var variable: 10328000
Address stored in ip variable: 10328000
Value of *ip variable: 20

在Go语言中的nil指针

Go编译器为指针变量分配一个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

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

要检查是否为nil指针,可以使用if语句,如下所示:

if(ptr != nil)     /* succeeds if p is not nil */
if(ptr == nil)    /* succeeds if p is null */

有关指针的详细信息

指针有很多但很简单的概念,它们对Go编程非常重要。下面几个重要的指针概念,对于Go程序员应该要清楚:

序号描述
1Go指针数组

可以定义数组来保存一些指针

2Go指针的指针

Go允许有指针指向指针等等

3Go语言传递指针到函数

通过引用或地址传递参数都允许被调用函数在调用函数中更改传递的参数。