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
这里,type 是指针的基本类型;它必须是有效的 C 数据类型,而 var-name 是指针变量的名称。你用来声明指针的星号 * 与用于乘法的星号相同。但是,在此语句中,星号用于将变量指定为指针。以下是有效的指针声明:
var ip *int /* pointer to an integer */ var fp *float32 /* pointer to a float */
所有指针的实际数据类型,无论是整数、浮点数还是其他类型,都是相同的,一个长十六进制数,表示内存地址。不同数据类型指针之间的唯一区别在于指针指向的变量或常量的类型。
如何使用指针?
有一些重要的操作,我们经常用指针来执行:(a)我们定义指针变量,(b)将变量的地址赋给指针,以及(c)访问指针变量中存储的地址处的值。
所有这些操作都是使用一元运算符 * 执行的,它返回位于其操作数指定的地址处的变量的值。以下示例演示如何执行这些操作:
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 中的空指针
如果你没有要分配的确切地址,Go 编译器会将空值分配给指针变量。这是在变量声明时完成的。分配为 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(零)值,则假定它不指向任何内容。
要检查空指针,可以使用 if 语句,如下所示:
if(ptr != nil) /* succeeds if p is not nil */ if(ptr == nil) /* succeeds if p is null */
Go 指针详解
指针有很多但容易理解的概念,它们对 Go 编程非常重要。Go 程序员应该清楚指针的以下概念:
序号 | 概念与描述 |
---|---|
1 |
Go - 指针数组
你可以定义数组来保存多个指针。 |
2 |
Go - 指向指针的指针
Go 允许你拥有指向指针的指针,依此类推。 |
3 |
在 Go 中将指针传递给函数
按引用或按地址传递参数都使被调用函数能够在调用函数中更改传递的参数。 |