请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

区别里第一条理解不了

“make 不仅分配内存,还会初始化,new 只会分配零值填充的值“
这句话怎么理解呢?make不也是只能分配零值填充吗?
区别里后面两条可以理解,除此之外也就make多一个容量,然后new指向nil了吧
但是这第一条真的很矛盾呀

正在回答

1回答

new(T)会为类型T分配内存,并返回一个指向该类型的指针,该指针指向的内存被初始化为类型T的零值。
这里关键是要理解分配零值填充的值的含义,像数值和字符创这种基本类型,使用new实例化后得到的是一个指针类型,而且使用零值进行填充。

实际上只要是使用new或者make进行实例化就一定分配了内存,因此得到的变量就不可能是nil了。
比如:

i := new(int)
fmt.Println(*i)
s1 := new(string)
fmt.Println(*s1)

这里变量i和s1并不是nil,而会被填充零值,也就是会得到一个值为0的指针类型的i和值为空字符串的指针类型的s1.

但如果是slice,map,channel这些容器类型
是如果使用make初始化,比如

s := make([]int, 5)

这里切片s不仅申请了5个存放int的空间,而且每个元素都会被填充0值,也就是会得到一个拥有5个元素的切片,只不过元素的值为0

但是如果使用new来实例化,会得到一个指针类型的切片,这个指针切片指向了一个空切片,这个切片没有任何元素,但需要注意的是,这个指针类型的切片本身虽然不是nil,但它的值指向了nil。

s2 := new([]int)

所以对于s2来说,虽然这个指针类型不是nil,但是它的指向的值会被填充零值,也就是*s2是等于nil的。

因此也特别需要留意map,slice这种类型
比如map类型,如果它的值是nil是无法直接使用的,如果直接增加元素就会抛出panic

m1 := new(map[int]int)
fmt.Println(*m1 == nil)
(*m1)[1] = 1

比如上面这个例子,给*m1增加元素的时候就会panic

1 回复 有任何疑惑可以回复我~
  • 提问者 Rex_HH #1
    理解了,谢谢老师
    回复 有任何疑惑可以回复我~ 2024-10-17 10:50:09
  • 提问者 Rex_HH #2
    我还是要问一下老师,这个nil是怎样一个存在呢?他是一个真实存在的值,还是只是一个地址。   
    比如new([]int) 这种方式,他是指针指向一个内存空间,然后里面存了个叫nil的值,
    还是有一个统一的地址,看见这个地址就知道他是nil。
    另外,如果new一个map或者channel,那它“间接值部”的那些复杂的数据数据结构会被新建吗?(这个可以叫间接值部吗)
    就比如map的桶或者channel的环形缓存那些,还是只是开辟一个地址,里面存上nil。
    回复 有任何疑惑可以回复我~ 2024-10-17 11:11:40
  • 少林码僧 回复 提问者 Rex_HH #3
    你的理解基本已经到位了。new函数用于分配内存并返回一个指向类型零值的指针。对于切片类型[]int来说,零值就是nil。所以当使用new([]int)时,它分配了一个指向切片的指针,这个指针本身有内存地址,不为nil,但是它所指向的切片值还没有被初始化,所以是nil。所它所指向的切片值还没有被初始化也就是间接值部的数据结构没有被创建,这也是它跟make的本质区别
    回复 有任何疑惑可以回复我~ 2024-10-17 22:30:00
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信