zoukankan      html  css  js  c++  java
  • Go语言中new()和make()的区别

    1. Go语言中的值类型和引用类型

    • 值类型:int,float,bool,string,struct数组 (数组要特别注意,别搞混了)

    变量直接存储值,分配栈区的内存空间,这些变量所占据的空间在函数被调用完后会自动释放。

    • 引用类型:slice,map,chan和值类型对应的指针

    变量存储的是一个地址(或者理解为指针),指针指向内存中真正存储数据的首地址。内存通常在堆上分配,通过GC回收。

    2. new() vs make()

    对值类型和引用类型了解之后,再来理解new()和make()就不难了,其实只要有C/C++背景的理解起来都不难。比如我们声明一个int类型的数据,一般是这样的:

    var i int

    var s string 

    当我们不指定变量的默认值时,这些变量的默认值就是对应的零值。(int类型的零值是0,string类型的零值是"",引用类型的零值是nil)。我们可以直接对值类型的变量进行赋值,修改变量对应的值等等。但是,如果声明的变量是引用类型呢?这就需要用到new()或make()函数了。先来看这样一个例子:

    var i int // 值类型
    i = 10
    fmt.Println(i) // 10
    
    var p *int // 引用类型
    *p = 10
    fmt.Println(*p) //panic: runtime error: invalid memory address or nil pointer dereference

    从例子可以看到,当对指针p进行赋值的时候,出现了panic,提示p 是无效的内存地址或是空指针引用。也就是说,对于引用类型的变量,我们不仅要声明变量(这仅仅是给变量取个名字),更重要的是,我们得手动为它分配空间!好在Go中还有GC,如果是C/C++,对于指针类型,除了手动申请空间,更要手动释放空间。

    new()方法就是为 int/bool/struct等 值类型分配内存空间,返回相应类型的指针;而make()就是专为slice,map,channel分配空间。

    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

    因此,我们可以稍稍修改上面错误的程序.

    var p *int // 引用类型,或者写成 p := new(int)
    p = new(int)
    *p = 10
    fmt.Println(*p) // 10 

    make()

    make也是用于内存分配,但是和new不同,它只用于slice、map和channel的内存创建,它返回的类型就是类型本身,而不是它们的指针类型。

    // 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
  • 相关阅读:
    TLS1.3 认证和秘钥建立握手环节的分析
    使用华为云+GitHub搭建自己的博客
    TLS1.3 握手协议的分析
    Formal Analysis of the TLS Handshake Protocol -----论文整理
    TLS1.3 握手过程特性的整理
    TLS1.3 PPT 整理
    SSL/TLS 握手协议简述
    TLS握手秘钥套件分析
    Scyther-Compromise 协议形式化安全分析如何改进协议
    HTTP 协议部分常识简介
  • 原文地址:https://www.cnblogs.com/kkbill/p/12540316.html
Copyright © 2011-2022 走看看