在Go语言中,make函数专门用于初始化slice、map和channel类型的对象。它分配所需的数据结构,并返回一个可以使用的对象(不是指针!)。
示例:
s := make([]int, 5, 10) // 长度为5,容量为10的切片 m := make(map[string]int) // 空map ch := make(chan int, 2) // 容量为2的缓冲通道
细节:
slice,参数:长度(len)和(可选)容量(cap)。map和chan——只有(可选的)容量(初始大小/缓冲)。make函数返回的对象已经初始化,准备好使用。make,它们通过字面量或new进行初始化(new返回的是零值的指针)。与new的比较:
new(T)返回*T,所有字段均为零。make(T)仅返回三种类型的T:slice、map、chan。可以通过new而不是make获取工作中的map吗?
m := new(map[string]int) (*m)["a"] = 1 // 会发生什么?
许多人认为这是正确的,但会在运行时引发panic:assignment to entry in nil map。因为在变量*m中是nil!
**正确的做法:**使用make:
m := make(map[string]int) m["a"] = 1 // 好的
故事
在一个微服务中,用var cache map[string]interface{}创建map而未初始化make,导致在写入时出现panic,生产环境中的stack trace令人困惑。只有在分析代码后发现问题:map为nil。
故事
在编写数据管道时,忘记了通道的缓冲,使用make(chan int)创建,结果导致goroutine卡住,等待读取,而预期是异步交换。这个错误只有在大规模测试时才被发现。
故事
在一个通过new进行初始化的项目中,一些开发人员尝试使用new([]int)而不是make([]int, 10),最终得到了一个指向nil切片的指针,并在第一次写入时发生运行时panic。