donglun2024 2016-07-23 04:57
浏览 8
已采纳

新函数与未初始化变量的区别

What's the difference of new function and uninitialized variable? What's the advantage of both?

s := new(string) // *string
var s *string    // *string
var s string     // string

Is it only for simplicity the code? Because i think it's same

s := new(string) /* same as */ var s *string = &emptyString
  • 写回答

2条回答 默认 最新

  • dongnuoyi8833 2016-07-23 08:03
    关注

    first difference:

    The built-in function new takes a type T, allocates storage for a variable of that type at run time

    2nd difference: new initializes allocated string to empty string ("") and initializes pointer to the address of this string, but var ptr2 *string just initializes ptr2 to nil and do not allocates any string:

    sample code A (with commented output):

    ptr := new(string)               // *ptr has value "", ptr: static type *string
    fmt.Println(len(*ptr))           // 0
    fmt.Println(cap([]byte(*ptr)))   // 32
    fmt.Printf("%T %q
    ", ptr, *ptr) // *string ""
    

    sample code B (with commented output):

    var ptr2 *string                // ptr2 has value nil, static type *string
    fmt.Printf("%T %#[1]v
    ", ptr2) // *string (*string)(nil)
    //fmt.Println(len(*ptr2)) // panic: runtime error: invalid memory address or nil pointer dereference
    //fmt.Println(cap([]byte(*ptr2)))
    

    sample code C (with commented output):

    var str string                // str has value "", static type string
    fmt.Println(len(str))         // 0
    fmt.Println(cap([]byte(str))) // 32
    fmt.Printf("%T %[1]q
    ", str) // string ""
    

    Allocation:

    The built-in function new takes a type T, allocates storage for a variable of that type at run time, and returns a value of type *T pointing to it. The variable is initialized as described in the section on initial values.

    new(T)
    

    For instance

    type S struct { a int; b float64 }
    new(S)
    

    allocates storage for a variable of type S, initializes it (a=0, b=0.0), and returns a value of type *S containing the address of the location.

    ref: https://golang.org/ref/spec

    Allocation with new:

    Go has two allocation primitives, the built-in functions new and make. They do different things and apply to different types, which can be confusing, but the rules are simple. Let's talk about new first. It's a built-in function that allocates memory, but unlike its namesakes in some other languages it does not initialize the memory, it only zeros it. That is, new(T) allocates zeroed storage for a new item of type T and returns its address, a value of type *T. In Go terminology, it returns a pointer to a newly allocated zero value of type T.

    Since the memory returned by new is zeroed, it's helpful to arrange when designing your data structures that the zero value of each type can be used without further initialization. This means a user of the data structure can create one with new and get right to work. For example, the documentation for bytes.Buffer states that "the zero value for Buffer is an empty buffer ready to use." Similarly, sync.Mutex does not have an explicit constructor or Init method. Instead, the zero value for a sync.Mutex is defined to be an unlocked mutex.

    The zero-value-is-useful property works transitively. Consider this type declaration.

    type SyncedBuffer struct {
        lock    sync.Mutex
        buffer  bytes.Buffer
    } Values of type SyncedBuffer are also ready to use immediately upon allocation or just declaration. In the next snippet, both p and v
    

    will work correctly without further arrangement:

    p := new(SyncedBuffer)  // type *SyncedBuffer
    var v SyncedBuffer      // type  SyncedBuffer
    

    Allocation with 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. These examples illustrate the difference between new and make:

    var p *[]int = new([]int)       // allocates slice structure; *p == nil; rarely useful
    var v  []int = make([]int, 100) // the slice v now refers to a new array of 100 ints
    
    // Unnecessarily complex:
    var p *[]int = new([]int)
    *p = make([]int, 100, 100)
    
    // Idiomatic:
    v := make([]int, 100)
    

    Remember that make applies only to maps, slices and channels and does not return a pointer. To obtain an explicit pointer allocate with new or take the address of a variable explicitly.

    ref: https://golang.org/doc/effective_go.html

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器
  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)