Go指针

Go 支持指针操作。指针使得开发人员可以直接操作内存空间,能够有效地提升程序的执行性能,但是传统的指针容易带来指针偏移错误、忘记释放内存等问题,大大提升了指针编程的门槛。Go 移除了指针的运算能力,并引入了自动垃圾回收机制,使得 Go 中的指针在具备高效的内存访问效率同时,不会出现非法修改越界数据和指针占用内存忘记回收等问题.
指针(pointer)在Go语言中可以被拆分为两个核心概念:
  • 类型指针,允许对这个指针类型的数据进行修改,传递数据可以直接使用指针,而无须拷贝数据,类型指针不能进行偏移和运算。
  • 切片,由指向起始元素的原始指针、元素数量和容量组成。
受益于这样的约束和拆分,Go语言的指针类型变量即拥有指针高效访问的特点,又不会发生指针偏移,从而避免了非法修改关键性数据的问题。同时,垃圾回收也比较容易对不会发生偏移的指针进行检索和回收。
切片比原始指针具备更强大的特性,而且更为安全。切片在发生越界时,运行时会报出宕机,并打出堆栈,而原始指针只会崩溃。
要明白指针,需要知道几个概念:指针地址、指针类型和指针取值,
  1. 一个指针变量可以指向任何一个值的内存地址。
  2. 指针所指向的值的内存地址在 32 和 64 位机器上分别占用 4 或 8 个字节。
  3. 指针占用字节的大小与所指向的值的大小无关。
  4. 当一个指针被定义后没有分配到任何变量时,它的默认值为 nil。
  5. 指针变量通常缩写为 ptr
  6. 指针的值是带有0x十六进制前缀的一组数据
每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。Go语言中使用在变量名前面添加&操作符(前缀)来获取变量的内存地址(取地址操作)。变量、指针和地址三者的关系是,每个变量都拥有地址,指针的值就是地址。
Go 中的指针使用方式与 C 类似:“&” 为取址符号,“*” 为取值符号。声明一个指针类型如下
var name *T (T代表类型可以是 int string等)
var ip *int /* 指向整型*/ var fp *float32 /* 指向浮点型 */
当使用&操作符对普通变量进行取地址操作并得到变量的指针后,可以对指针使用*操作符,也就是指针取值
package main
import "fmt"
func main() {
name := "aoho"
p := &name
//指针变量指向原变量的值
fmt.Println("name is", *p) //aoho
// 改变指针地址指向的值
*p = "zhu"
fmt.Println("name is", name) //zhu
//打印地址
fmt.Printf("%p", p) //0xc000010200
//打印类型
fmt.Printf("p type: %T\n", p) // *string
}
另一种创建方法 new()函数
str := new(string)
//修改值
*str = "golang is better"
str := new(string)
fmt.Printf("p value: %v\n", str)
fmt.Printf("p type: %T\n", str)
*str = "GO"
fmt.Println(*str)
输出
p value: 0xc000010200
p type *string
GO
Go 空指针
当一个指针被定义后没有分配到任何变量时,它的值为 nil。
nil 指针也称为空指针。
nil在概念上和其它语言的null、None、nil、NULL一样,都指代零值或空值。
空指针的判断用 ptr == nil
Go指针数组、
声明整型指针数组
var ptr[3] *int
a := 2
ptr[0] = &a
指针数组是指数组的元素都是指针类型
数组的指针是说这个指针变量的值所指向的地址是数组的地址
Go指向指针的指针、
如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量
当定义一个指向指针的指针变量时,第一个指针存放第二个指针的地址,第二个指针存放变量的地址
声明指向指针的指针变量声明格式如下:
var ptr **int
例子:
var ptr **int
var a =3000
p:=&a
fmt.Println(p)
ptr = &p
fmt.Println(ptr)
Go向函数传递指针参数
func swap(*int, y *int) {
   var temp int
   temp = *x    /* 保存 x 地址的值 */
   *= *y      /* 将 y 赋值给 x */
   *= temp    /* 将 temp 赋值给 y */
}
 
swap(&a, &b);
小结:
两种创建方法
var name *string
name := new(string)
对变量进行取地址操作使用&操作符,可以获得这个变量的指针变量。
指针变量的值是指针地址。
对指针变量进行取值操作使用*操作符,可以获得指针变量指向的原变量的值。
空指针判断可以用nil
指向指针的指针就是指针的值是另个一个指向变量地址的指针

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注