内容简介:我们知道,变量的本质对一块内存空间的命名,可以通过引用变量名来使用这块内存空间存储的值,而指针的含义则指向存储这些变量值的内存地址。和 PHP、Java 不同,Go 语言支持指针,如果一个变量是指针类型的,那么就可以用这个变量来存储指针类型的值:如上,你可能记得 PHP 中也有类似通过
指针概述
我们知道,变量的本质对一块内存空间的命名,可以通过引用变量名来使用这块内存空间存储的值,而指针的含义则指向存储这些变量值的内存地址。和 PHP 、 Java 不同,Go 语言支持指针,如果一个变量是指针类型的,那么就可以用这个变量来存储指针类型的值:
a := 100 var ptr *int ptr = &a fmt.Println(ptr) fmt.Println(*ptr)
如上, ptr
就是一个指针类型,表示指向存储 int
类型值的指针。我们可以通过 *ptr
获取指针指向内存地址存储的变量值(我们通常将这种引用称作「间接引用」), ptr
本身是一个内存地址值(通过 &a
可以获取变量 a
所在的内存地址),所以上述代码打印结果是:
0xc0000a2000 100
你可能记得 PHP 中也有类似通过 &
进行引用传值的用法(数组传值需要,对象传值不需要,因为对象本身是引用类型),其实这种用法的本质也是指针,只不过 PHP 的语言级别屏蔽了指针的概念而已。
Go 语言之所以引入指针类型,主要基于两点考虑,一个是为 程序员 提供操作变量对应内存数据结构的能力;另一个是为了提高程序的性能(指针可以直接指向某个变量值的内存地址,可以极大节省内存空间,操作效率也更高),这在系统编程、操作系统或者网络应用中是不容忽视的因素。
指针在 Go 语言中有两个使用场景:
- 类型指针
- 数组切片
作为类型指针时,允许对这个指针类型的数据进行修改指向其它内存地址,传递数据时如果使用指针则无须拷贝数据从而节省内存空间,此外和 C 语言中的指针不同,Go 语言中的类型指针不能进行偏移和运算,因此更为安全。
数组切片我们前面已经介绍过,由指向起始元素的原始指针、元素数量和容量组成,所以切片与数组不同,是引用类型,而非值类型。
指针的基本使用
下面我们以一个简单的示例代码来演示 Go 语言中指针的基本使用。
指针类型的声明和初始化
指针变量在传值时之所以可以节省内存空间,是因为指针指向的内存地址的大小是固定的,在 32 位机器上占 4 个字节,在 64 位机器上占 8 个字节,这与指针指向内存地址存储的值类型无关。
关于指针类型的声明我们在开头已经演示过,这里我们再回头看下这段代码:
var ptr *int fmt.Println(ptr) a := 100 ptr = &a fmt.Println(ptr) fmt.Println(*ptr)
当指针被声明后,没有指向任何变量内存地址时,它的零值是 nil,然后我们可以通过在给定变量前加上取地址符 &
获取变量对应的内存地址将其赋值给声明的指针类型,这样,就是对指针的初始化了,然后我们可以通过在指针类型前加上间接引用符 *
获取指针指向内存空间存储的变量值。当然,我们也可以通过 :=
对指针进行初始化:
a := 100 ptr := &a fmt.Printf("%p\n", ptr) fmt.Printf("%d\n", *ptr)
底层会自动判断指针的类型,在格式化输出时,可以通过 %p
来标识指针类型。
通过指针传值
我们再来看一个通过指针传值的示例,通过指针传值就类似于 PHP 中通过引用传值,这样做的好处是节省内存空间,此外还可以在调用函数中实现对变量值的修改,因为直接修改的是指针指向内存地址上存储的变量值,而不是值拷贝。
为了体现出区别,我们先看不使用指针的值拷贝示例:
func swap(a, b int) { a, b = b, a fmt.Println(a, b) } func main() { a := 1 b := 2 swap(a, b) fmt.Println(a, b) }
上述代码的打印结果是:
下面我们通过指针传值来重构上述代码:
func swap(a, b *int) { *a, *b = *b, *a fmt.Println(*a, *b) } func main() { a := 1 b := 2 swap(&a, &b) fmt.Println(a, b) }
上述代码的打印结果是
因为这次,我们是通过指针传值的( &a
、 &b
都是指针,只不过我们没有显示声明而已),直接会对内存地址存储变量值进行交换操作,而主函数中的 a
、 b
变量仅仅是对应内存存储空间的别名而已,所以调用完 swap
函数后,它们所对应的内存空间存储值已经交换过来了。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- python(函数指针和类函数指针)
- 将数组和矩阵传递给函数,作为C中指针的指针和指针
- C/C++ 函数指针
- flag 中的 Go 函数指针
- CGO 中传递回调函数和指针
- GOLAMG-5 type 不同于C/C++ typedef,切片底层是指针域的函数指针
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Transcending CSS
Andy Clarke、Molly E. Holzschlag / New Riders / November 15, 2006 / $49.99
As the Web evolves to incorporate new standards and the latest browsers offer new possibilities for creative design, the art of creating Web sites is also changing. Few Web designers are experienced p......一起来看看 《Transcending CSS》 这本书的介绍吧!