Go基础——指针

10.指针

go语言是值传递, 例子如下

func main() {
	// a := 100
	// b := &a // 取a地址,将指针保存到b中
	// fmt.Printf("type of b:%T\n", b)
	// c := b // 根据指针取值
	// fmt.Printf("type of c:%T\n", c)
	// fmt.Printf("value of c:%v\n", c)
	x := 10
	changeValue(x)
	fmt.Println("x:", x)
	changeValue2(&x)
	fmt.Println("x:", x)
}

func changeValue(x int) {
	x = 100
}

func changeValue2(y *int) {
	*y = 100
}
/*
x: 10
x: 100
*/

go语言指针不同于c/c++, 不能进行偏移和运算,是安全指针

指针:任何程序数据载入内存后,在内存都有他们的地址,这就是指针。

为了保存一个数据在内存中的地址,就需要指针变量。

10.1 基本操作

  • &:取地址
  • *:根据地址取值

Go语言中的值类型(int、float、bool、string、array、struct)都有对应的指针类型,如:*int*int64*string

  • 指针变量的值是指针地址。
  • 对指针变量进行取值*操作,可以获得指针变量指向的原变量的值
ptr := &temp

temp:被取地址的变量, 类型为*T

ptr:用于接受地址的变量,称作指针类型, 类型为*T

	a := 10
	b := &a
	fmt.Printf("a:%v, ptr a:%p\n", a, &a)
	fmt.Printf("b:%v, ptr b:%p\n", b, b)
	fmt.Printf("b:%v, ptr b:%p\n", b, &b)
/*
	a:10, ptr a:0xc000016088
	b:0xc000016088, ptr b:0xc000016088
	b:0xc000016088, ptr b:0xc000006028
*/
	a := 100
	b := &a // 取a地址,将指针保存到b中
	fmt.Printf("type of b:%T\n", b)
	c := b // 根据指针取值
	fmt.Printf("type of c:%T\n", c)
	fmt.Printf("value of c:%v\n", c)
/*
type of b:*int
type of c:int
value of c:100
*/

10.2make, new分配内存空间

	var a *int
// a := new(int)就行了
	*a = 1000
	fmt.Println(*a)

	var b map[string]int
	b["xs"] = 1000
	fmt.Println(b)

第一段:/*
var a *int只是声明了一个指针变量a但是没有初始化,指针作为引用类型需要初始化后才会拥有内存空间,才可以给它赋值。
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x1 addr=0x0 pc=0x9cc516]

goroutine 1 [running]:
main.main()
        D:/Go/learn/2/src/ptr.go:7 +0x16
exit status 2
*/
第二段:/*
panic: assignment to entry in nil map

goroutine 1 [running]:
main.main()
        D:/Go/learn/2/src/ptr.go:11 +0x2e
exit status 2
*/

这两段都会报错

第一段:var a *int只是声明了一个指针变量a但是没有初始化,指针作为引用类型需要初始化后才会拥有内存空间,才可以给它赋值。

对于引用类型的变量,我们在使用的时候不仅要声明它,还要为它分配内存空间,否则值就没办法存储。而对于值类型的声明不需要分配内存空间,是因为它们在声明的时候已经默认分配好了内存空间。

10.2.1new

new函数不太常用,使用new函数得到的是一个类型的指针,并且该指针对应的值为该类型的零值。

a := new(int)
fmt.Printf("%T, %v, %d", a, a, *a)

/*
*int, 0xc000016088, 0
*/
	var a *int
// a := new(int)就行了
	*a = 1000
	fmt.Println(*a)

10.2.2make

make也是用于内存分配的,区别于new,它只用于slice、map以及chan的内存创建,而且它返回的类型就是这三个类型本身,而不是他们的指针类型,因为这三种类型就是引用类型,所以就没有必要返回他们的指针了。

make(map[string]int, 10)

new, make区别

  1. 都是用来做内存分配的。
  2. make只用于slice、map以及channel的初始化,返回的还是引用类型本身;
  3. new用于类型的内存分配,并且内存对应的值为类型零值,返回的是指向类型的指针。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值