今天遇到一个这样的问题

Go 结构体指针初始化_初始化


同样都是查询,上面的就不需要new, 而下面的就需要new

请教了一下大佬,

下面的是一个结构体指针,需要分配内存才能使用

在别的地方也找到了印证,(尽管之前博客提到过这个问题,)


官方文档

// The new built-in function allocates memory. The first argument is a type,
// not a value, and the value returned is a pointer to a newly
// allocated zero value of that type.
func new(Type) *Type

翻译出来就是:new是一个分配内存的内置函数,第一个参数是类型,而不是值,返回的值是指向该类型新分配的零值的指针。 我们平常在使用指针的时候是需要分配内存空间的,未分配内存空间的指针直接使用会使程序崩溃,

var b *int8
*b = 10

比如这样就报错了。
声明了一个指针变量,直接就去使用它,就会使用程序触发panic,因为现在这个指针变量在内存中没有块地址属于它,就无法直接使用该指针变量,所以new函数的作用就出现了,通过new来分配一下内存,就没有问题

var b *int64 = new(int64)
 *b = 10

// 数组
	array := new([5]int)
	fmt.Printf("-array:-%p---%#v---\n", &array, array)//-array:-0xc000006028---&[5]int{0, 0, 0, 0, 0}---
	//array[0] = 2
	(*array)[0] = 2
	fmt.Printf("-array:-%p---%#v---\n", &array, array) //-array:-0xc000006028---&[5]int{2, 0, 0, 0, 0}---
// 切片
	slice := new([]int8)
	fmt.Printf("-slice:-%p---%#v---\n", &slice, slice) //--slice:-0xc000006038---&[]int8(nil)---
	(*slice)[0] = 2
	//slice[2] = 5 // invalid operation: slice[2] (type *[]int8 does not support indexing)
	fmt.Printf("-slice:-%p---%#v---\n", &slice, slice)//panic: runtime error: index out of range [0] with length 0
//map
     m := new(map[string]int)
	fmt.Printf("--map:--%p------%3v\n", &m, m) //--map:--0xc000006028------&map[]
	(*m)["xiaosheng"] = 4
	fmt.Printf("--map:--%p------%3v\n", &m, m) //panic: assignment to entry in nil map
// channel
	// channel
	channe := new(chan string) //--chan:--0xc000006028------0xc000006030
	fmt.Printf("--chan:--%p------%3v\n", &channe, channe)
	channe <- "ddd"  // invalid operation: channe <- "ddd" (send to non-chan type *chan string)

使用new函数分配内存后,只有数组在初始化后可以直接使用,slice、map、chan初始化后还是不能使用,会触发panic,这是因为slice、map、chan基本数据结构是一个struct,也就是说他里面的成员变量仍未进行初始化,所以他们初始化要使用make来进行,make会初始化他们的内部结构


下面这段代码在执行时候会触发panic, 我猜测是因为长度没有分配,而对一个长度没有分配的数组进行索引操作,就报索引越界错误,有大佬知道的话欢迎指点一下,

m := make([]int, 0, 10)
	m[8] = 12
	fmt.Println(m)