• 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

  • 相关阅读:
    Python - 小玩意 - 键盘记录器
    PIM其它特性——IPv6、Anycast RP
    数据治理建设管理办法(参考)(粉丝福利)
    C++ string类
    让python代码找到文件路径的最好方法
    使用水泥混凝土摊铺机进行建设公路项目有这样的特点
    详细指南:如何使用基于Double-Array Trie树的PHP扩展实现垃圾邮件过滤器
    gitlab克隆本地切换p分支
    C#调用Windows系统自带虚拟键盘的方法
    Qt编程,TCP编程、数据库
  • 原文地址:https://blog.csdn.net/junlaiyan/article/details/127758130