• golang make和new的区别


    先写用例验证,

    func TestMake(t *testing.T) {
    	a := make([]string, 0)
    	fmt.Println(a == nil, a, &a, len(a), reflect.TypeOf(a), reflect.TypeOf(a).Kind())
    	println(a, &a, len(a))
    	b := new([]string)
    	fmt.Println(b == nil, b, *b, len(*b), reflect.TypeOf(b), reflect.TypeOf(b).Kind())
    	println(b, *b, len(*b))
    
    	c := make(map[string]string, 0)
    	fmt.Println(c == nil, c, reflect.TypeOf(c).Kind())
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    === RUN   TestMake
    false [] &[] 0 []string slice
    [0/0]0xe5f1a8 0xc0000040d8 0
    false &[] [] 0 *[]string ptr
    0xc000004150 [0/0]0x0 0
    false map[] map
    --- PASS: TestMake (0.00s)
    PASS
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    从输出结果看出,make和new都分配了内存,但make返回的是值对象,new返回的是指针

    为什么go要设置对象创建的两种方式:一个返回值,一个返回new。从使用的角度来,显得有些多余。但总是有原因的:

    golang编译器设置了”zero value”的感念,也就是编译阶段,为你声明的变量赋予一个默认值。 官方文档说明

    When storage is allocated for a variable, either through a declaration
    or a call of new, or when a new value is created, either through a
    composite literal or a call of make, and no explicit initialization is
    provided, the variable or value is given a default value. Each element
    of such a variable or value is set to the zero value for its type :
    false for booleans, 0 for numeric types, “” for strings, and nil for
    pointers, functions, interfaces, slices, channels, and maps
    . This
    initialization is done recursively, so for instance each element of an
    array of structs will have its fields zeroed if no value is specified.

    从以上说明可以看出,

    • 一个变量内存空间分配,通过声明定义式,或使用new关键字,或者创建一个新值三种方式。
    • 如果只是声明定义,没有显式给初始值。变量使用默认值,也就是zero value。基本数据类型:布尔类型false, 数值类型0, 字符串类型“”;slice,map,channel等引用类型为nil
    • 初始值的显式创建,使用composite literal,或者调用make方法。(composite literal理解:基本类型直接赋值,复杂数据结构直接创建value对象并赋值。例如 var a map[string]string = map[string]string{"name":"Jack"})
    • 编译器给变量设置默认值时,会递归设置。例如,一个结构体数组中的每个元素的每个field都会被设置为对应的zero value

    这也是官方文档中关于make的说明,slice,map,channel使用前,必须先通过make的初始化

    Back to allocation. The built-in function make(T, args) serves a
    purpose different from new(T). It creates slices, maps, and channels
    only, and it returns an initialized (not zeroed) value of type T (not
    *T)
    . The reason for the distinction is that these three types represent, under the covers, references to data structures that must
    be initialized before use
    . A slice, for example, is a three-item
    descriptor containing a pointer to the data (inside an array), the
    length, and the capacity, and until those items are initialized, the
    slice is nil. For slices, maps, and channels, make initializes the
    internal data structure and prepares the value for use. For instance,

    make([]int, 10, 100) allocates an array of 100 ints and then creates a
    slice structure with length 10 and a capacity of 100 pointing at the
    first 10 elements of the array. (When making a slice, the capacity can
    be omitted; see the section on slices for more information.) In
    contrast, new([]int) returns a pointer to a newly allocated, zeroed
    slice structure, that is, a pointer to a nil slice value
    .

    另外,推荐一篇关于zero value ,nil, empty struct的区别和使用说明
    https://juejin.cn/post/6895231755091968013

  • 相关阅读:
    深度学习基础:循环神经网络中的长期依赖问题
    (10)(10.8) 固件下载
    JVM 运行时数据区和垃圾收集算法
    Vue47-修改默认配置webpack.config.js文件
    RTSP 服务器实例 live555 源代码分析
    golang 在 Mac、Linux、Window 下交叉编译
    wkhtmltopdf命令行示例
    What‘s new in PikiwiDB(Pika) v3.5.3(正式版)
    ASP.NET MVC--数据验证
    “攻城狮”如何写高逼格的代码
  • 原文地址:https://blog.csdn.net/junlaiyan/article/details/127758130