Tags: #go #performance
make
: allocates memory to hold a built-in type (slice, map or channel) with len
and cap
(capacity) set accordingly to the type’s zero value (immediately usable).new
: allocates memory to hold both built-in and custom user types with fields zeroed, not immediately usable for some types.NOTE: This means
t := new(T)
andvar t *T
are equivalent.
Example:
m := new(int)
fmt.Printf("%+v | %p | %T\n", *m, m, m) // 0 | 0xc000110008 | *int`
package main
import (
"fmt"
)
func main() {
// The new built-in function allocates memory.
// The first argument is a type, not a value.
// The value returned is a pointer to a newly allocated zero value of that type.
p := new([]int)
// len, cap == 0
fmt.Println("underlying array should be nil, i.e. comparison should return true:", *p == nil)
// we can't append to p (as p is a pointer)
// so we have to dereference p to append to it
// also *p == nil until we append to the underlying array
// once we've appended some data the underlying array is no longer nil
*p = append(*p, 1)
fmt.Println("underlying array should no longer be nil, i.e. comparison should return false:", *p == nil)
// 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.
v := make([]int, 5, 10)
// len = 5, cap = 10
fmt.Println("v should not be nil, i.e. comparison should return false:", v == nil)
fmt.Printf("\np:\n%+v\n%T\n\n", p, p) // &[]
fmt.Printf("v:\n%+v\n%T\n\n", v, v) // [0 0 0 0 0]
}