go中 slice chan map为什么需要用make初始化

zackzhangkai · 2020-07-16 14:42:22 · 2055 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2020-07-16 14:42:22 的主题,其中的信息可能已经有所发展或是发生改变。

    var mm = make(map[int]string)  //这个是用make申明
    fmt.Println(mm)  //输出map[]
    var mm2 map[int]string  //这个是像普通类型一样申明
    fmt.Println(mm2)  //输出map[]

    mm = map[int]string{9:"nine", 7:"seven"}
    mm2 = map[int]string{8:"eight", 4:"four"}
    fmt.Println(mm)  
    fmt.Println(mm2)

go中 为什么需要用make来初始化?直接像普通数据类型一样用var申明不就好了吗?我看效果也是一样的,有什么区别?

var mm = make(map[int]string)var mm2 map[int]string 感觉都给变量初始化了。


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2055 次点击  
加入收藏 微博
6 回复  |  直到 2020-07-20 10:19:02
colinrs
colinrs · #1 · 5年之前
package main

import "fmt"

func main() {
    var mm = make(map[int]string)  //这个是用make申明,make 的作用是初始化内置的数据结构,可以对切片、哈希表和 Channel进行初始化;
    fmt.Println(mm==nil)  //输出map[],这里的mm2 不是nil值

    var mm2 map[int]string  //这个是像普通类型一样申明,这里的mm2 是nil值
    fmt.Println(mm2==nil)  //输出map[]

    mm = map[int]string{9:"nine", 7:"seven"}
    mm2 = map[int]string{8:"eight", 4:"four"}
    fmt.Println(mm)  
    fmt.Println(mm2)
}
  • Q:go中 为什么需要用make来初始化
  • A: make 可以进行内存的预分配

  • Q:直接像普通数据类型一样用var申明不就好了吗?我看效果也是一样的,有什么区别?

  • A: 这两者是有区别的,见上面代码注释
jiuker
jiuker · #2 · 5年之前
  • 实际工程中可以使用 map[int]string{}{}代替,减少心智负担,什么new ,make 都不需要
  • 当然有些场景是只需要类型的,用于反射获取类型,比如errors.Is就是这么干的
  • struct{}{},[]int{},map[int]int{}一梭子干到底
thinkgos
thinkgos · #3 · 5年之前

一梭到底说明你对new和make的区别并不了解, 比如:

   new([]int),make([]int,0),[]int{},*[]int{},  
  new(map[int]string),make(map[int]string),map[int]string{},*map[int]string,

是有区别又有关系的,不同场合需要不同的使用. 不过实际,map比较少那么用,而slice是有场合使用的

jiuker
jiuker · #4 · 5年之前
thinkgosthinkgos #3 回复

一梭到底说明你对new和make的区别并不了解, 比如: ``` new([]int),make([]int,0),[]int{},*[]int{}, new(map[int]string),make(map[int]string),map[int]string{},*map[int]string, ``` 是有区别又有关系的,不同场合需要不同的使用. 不过实际,map比较少那么用,而slice是有场合使用的

这点还是知道的,只是不知道,什么场合只能用new ,什么场合只能用make ? chan(这个必须make)? 预留容量?申明最大空间?实际工程你敢用?

thinkgos
thinkgos · #5 · 5年之前
jiukerjiuker #4 回复

#3楼 @thinkgos 这点还是知道的,只是不知道,什么场合只能用new ,什么场合只能用make ? chan(这个必须make)? 预留容量?申明最大空间?实际工程你敢用?

用new的场合极少,目前暂时没遇到过. 当然,有的面试会问这个区别的.区别涉及一些底层原理. 用make有时的确需要申明最大空间或预留容量.实际工程我就用过.因为我非常清楚需求多大空间来避免多次扩容带来的性能损失. 像slice每次扩容在小于1024都是2倍扩容,一扩容就要引起数据拷贝.

jiuker
jiuker · #6 · 5年之前
thinkgosthinkgos #5 回复

#4楼 @jiuker 用new的场合极少,目前暂时没遇到过. 当然,有的面试会问这个区别的.区别涉及一些底层原理. 用make有时的确需要申明最大空间或预留容量.实际工程我就用过.因为我非常清楚需求多大空间来避免多次扩容带来的性能损失. 像slice每次扩容在小于1024都是2倍扩容,一扩容就要引起数据拷贝.

一般这种数组都可以重复利用,arr = arr[:0],就变成了新的,地址不变,容量以前使用的一致,岂不爽哉

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传