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