[Go] Data Allocation


new()


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.
  • it's helpful to arrange when designing your data structures that the zero value of each type can be used without further initialization.
  • Constructor

  • Sometimes the zero value isn't good enough and an initializing constructor is necessary. We can simplify a lot of boiler plate using a composite literal, which is an expression that creates a new instance each time it is evaluated.
  • f := File{fd, name, nil, 0}
    return &f
  • Unlike in C, it's perfectly OK to return the address of a local variable; the storage associated with the variable survives after the function returns. In fact, taking the address of a composite literal allocates a fresh instance each time it is evaluated, so we can combine these last two lines.
  • return &File{fd, name, nil, 0}
  • If a composite literal contains no fields at all, it creates a zero value for the type. The expressions new(File) and &File{} are equivalent.
  • make()

    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.
    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)