zoukankan      html  css  js  c++  java
  • golang中,new和make的区别

    在golang中,make和new都是分配内存的,但是它们之间还是有些区别的,只有理解了它们之间的不同,才能在合适的场合使用。

    简单来说,new只是分配内存,不初始化内存; 而make即分配又初始化内存。所谓的初始化就是给类型赋初值,比如字符为空,整型为0, 逻辑值为false等。

    new

    先看下new函数的定义

    // The new built-in function allocates memory. The first argument is a type,
    // not a value, and the value returned is a pointer to a newly
    // allocated zero value of that type.
    func new(Type) *Type
    

    可以看出,它的参数是一个类型,返回值为指向该类型内存地址的指针,同时会把分配的内存置为零,也就是类型的零值, 即字符为空,整型为0, 逻辑值为false

    看几个new的示例

       type P struct{
    		Name string
    		Age int
    	}
    	var a *[2]int
    	var s *string
    	var b *bool
    	var i *int
    	var ps *P
    
    	a = new([2]int)
    	s = new(string)
    	b = new(bool)
    	i = new(int)
    	ps = new(P) //结构
    
    	fmt.Println(a, " ", *a)
    	fmt.Println(s,  " ",*s)
    	fmt.Println(b,  " ",*b)
    	fmt.Println(i,  " ",*i)
    	fmt.Println(ps, " ", *ps)
    

    输出结果如下

    &[0 0]   [0 0]
    0xc00000e1e0   
    0xc00001a07a   false
    0xc00001a090   0
    &{ 0}   { 0}
    

    上面示例是基本的类型,再看下slice, map,chan这些用new咋操作

        map操作
        var mp *map[string]string
    	mp = new(map[string]string)
    	//*mp = make(map[string]string)  //这行注掉会panic "panic: assignment to entry in nil map""
    	(*mp)["name"] = "lc"
    	fmt.Println((*mp)["name"])
    	
    	slice操作
    	var ms *[]string
    	ms = new([]string)
    	//*ms = make([]string,5) //这行注掉会pance "panic: runtime error: index out of range"
    	(*ms)[0] = "lc"
    	fmt.Println((*ms)[0])
    	
    

    上面可以看出,silce、map、channel等类型属于引用类型,引用类型初始化为nil,nil是不能直接赋值的,也不能用new分配内存,还需要使用make来分配。

    make

    看下make的函数声明

    / The make built-in function allocates and initializes an object of type
    // slice, map, or chan (only). Like new, the first argument is a type, not a
    // value. Unlike new, make's return type is the same as the type of its
    // argument, not a pointer to it. The specification of the result depends on
    // the type:
    //	Slice: The size specifies the length. The capacity of the slice is
    //	equal to its length. A second integer argument may be provided to
    //	specify a different capacity; it must be no smaller than the
    //	length. For example, make([]int, 0, 10) allocates an underlying array
    //	of size 10 and returns a slice of length 0 and capacity 10 that is
    //	backed by this underlying array.
    //	Map: An empty map is allocated with enough space to hold the
    //	specified number of elements. The size may be omitted, in which case
    //	a small starting size is allocated.
    //	Channel: The channel's buffer is initialized with the specified
    //	buffer capacity. If zero, or the size is omitted, the channel is
    //	unbuffered.
    func make(t Type, size ...IntegerType) Type
    

    可以看出,它返回的就是类型本身,而不是指针类型,因为make只能给slice,map,channel等初始化内存,它们返回的就是引用类型,那么就没必要返回指针了

    看下make的一些示例

        mm :=make(map[string]string)
    	mm["name"] = "lc"
    	fmt.Println(mm["name"])
    
    	mss :=make([]int,2)
    	mss[0] = 100
    	fmt.Println(mss[0])
    
    	ch :=make(chan int,1)
    	ch <-100
    
    	fmt.Println(<-ch)
    

    小结

    make 仅用来分配及初始化类型为 slice、map、chan 的数据。new 可分配任意类型的数据.
    new 分配返回的是指针,即类型 *Type。make 返回引用,即 Type.
    new 分配的空间被清零, make 分配空间后,会进行初始化.

  • 相关阅读:
    自动化测试-短信验证码处理
    使用HttpClient调用WebAPI接口,含WebAPI端示例
    C#使用HttpClient上传文件并附带其他参数
    WebClient和HttpClient, 以及webapi上传图片
    C#-微信公众平台接口-上传临时素材
    字节组数(二进制流)、Base64、图片(文件)、二进制相互之间转换
    理解并设计rest/restful风格接口
    使用RESTful风格开发
    GitHub OAuth 第三方登录示例教程
    OAuth 2.0 的四种方式
  • 原文地址:https://www.cnblogs.com/ExMan/p/13804057.html
Copyright © 2011-2022 走看看