golang中指针,new和make函数作用

Posted Leo Han

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang中指针,new和make函数作用相关的知识,希望对你有一定的参考价值。

我们知道golang中的传递都是基于值传递,如果一个结构体比较大,这时候值传递需要复制的内容就比较多同时由于是基于值复制,耗费空间和时间,另外,基于值传递我们在调用的函数中对传入的参数进行修改,对于原值是没有任何影响的,也就是我们无法在函数中对传入的参数的原值进行修改
因此golang中提供了指针,和c、c++中的指针的概念类似,这时候传递的是指针,也是值复制,但是复制的是指针(指针比较小),这样我们既能够快速的将参数传递过去,同事也能够对原值进行修改。

需要注意的是,golang中存在另种内存模块,即我们常说的堆和栈,函数一般在栈上运行,局部变量在栈上分配,当函数结束之后,函数栈被回收,但是golang运行时会判断如果这个局部变量在函数结束之后还有其他区域引用,则会在栈上分配:

func testHeap() *model.JobInfo
	jobInfo := model.JobInfo
	return &jobInfo

这段代码如果在C中是会出问题的,因为C中函数结束之后,除非是显示调用maclloc在堆上分配空间,在栈上分配的都会被回收,返回的地址空间内容将不可知。
但是在golang中是可以运行的,因为golang运行时会自动判断外部是否还需要引用,如果需要引用这个的话,那么这个变量就不会在栈上分配,而是在堆上分配,golang的垃圾回收的作用区间也是在堆上。

指针是一种数据类型,其存储的是一个内存地址,该地址指向一个实际的内存单元

golang中声明指针一般如下:
var ptrName *prtType

var strPtr *string

这样我们就声明了一个类型为*string的指针,这时候strPtr的内容实际上是nil,而对指针变量赋值需要用到&取地址运算符:

	var strPtr *string
	str := "hello world"
	strPtr = &str
	fmt.Println(*strPtr)

而如果我们要获取指针对应的实际内容,需要用到取内容运算符*:

    // 打印 0xc000038790
    fmt.Println(strPtr)
    // 打印 hello world
	fmt.Println(*strPtr)

可以看到,打印指针变量的值对应的是一个地址,而取改地址的内容则是实际的值。

指针是可以有多个结合的,指向指针的指针:

	intVal := 10
	var intPtr *int
	var intPtrPtr **int
	intPtr = &intVal
	intPtrPtr = &intPtr
	fmt.Println("intPtrPtr = ",intPtrPtr)
	fmt.Println("*intPtrPtr = ",*intPtrPtr)
	fmt.Println("intPtr = ",intPtr)
	fmt.Println("**intPtrPtr = ",**intPtrPtr)
	fmt.Println("*intPtr = ",*intPtr)

打印如下:

intPtrPtr =  0xc0000d8020
*intPtrPtr =  0xc0000ac970
intPtr =  0xc0000ac970
**intPtrPtr =  10
*intPtr =  10

还可以更多的指针结合:

var intPtrPtr ***int

指向数组的指针:

var ptrArr [3]*int

指向结构体的指针

指向结构体的指针我们可以使用两种方式来进行初始化,一种是使用&取地址运算符,另外一种是使用new运算符:

	var jobPtr *model.JobInfo
	jobInfo := model.JobInfo
	jobPtr = &jobInfo
	jobPtr = new(model.JobInfo)
	jobPtr.Id = 12345

一般我们通过new和make来创建指针,一般而言

  • new 函数只用于分配内存,并且将内存清零(c、c++不会清零),返回一个对应类型的零值的指针
  • make只用于slice、chan、map这三种内置类型的创建和初始化

以上是关于golang中指针,new和make函数作用的主要内容,如果未能解决你的问题,请参考以下文章

Golang basic_leaming指针

golang 内置函数new()

golang:make和new的区别

Golang new 和 make 的区别

Golang make和new的区别及实现原理详解

go语言的new和make