table of Contents
Three, the difference between new and make
Many friends didn't understand why there are two functions for allocating memory when they first came into contact with Golang: new and make. As the saying goes: Existence is reasonable. Let's explain in detail the difference between the two.
One, new
Look at the function declaration first:
func new(Type) *Type
new is a built-in function of Golang, which is used to allocate memory. The first parameter is the type and the return value is the pointer of the type. Its value is initialized to "zero" (zero value corresponding to the type, int is initialized to 0, bool Initialized to false, etc.).
E.g:
package main
import "fmt"
func main() {
id := new(int)
name := new(string)
flag := new(bool)
fmt.Printf("id type: %T value: %v\n", id, *id)
fmt.Printf("name type: %T value: %v\n", name, *name)
fmt.Printf("flag type: %T value: %v\n", flag, *flag)
}
Output:
id type: *int value: 0
name type: *string value:
flag type: *bool value: false
As can be seen from the above example, the initialized "zero" value differs according to the type. The integer is initialized to 0, the string is initialized to empty, and the bool type is initialized to false.
Two, make
Look at the function declaration first:
func make(t Type, size ...IntegerType) Type
make is a built-in function of Golang. It is only used to allocate and initialize slice, map, and channel types of objects. All three types are structures. The return value is a type, not a pointer.
Slice source code structure:
type slice struct {
array unsafe.Pointer //指针
len int //长度
cap int //容量
}
Map source code structure:
// A header for a Go map.
type hmap struct {
// Note: the format of the hmap is also encoded in cmd/compile/internal/gc/reflect.go.
// Make sure this stays in sync with the compiler's definition.
count int // # live cells == size of map. Must be first (used by len() builtin)
flags uint8
B uint8 // log_2 of # of buckets (can hold up to loadFactor * 2^B items)
noverflow uint16 // approximate number of overflow buckets; see incrnoverflow for details
hash0 uint32 // hash seed
buckets unsafe.Pointer // array of 2^B Buckets. may be nil if count==0.
oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing
nevacuate uintptr // progress counter for evacuation (buckets less than this have been evacuated)
extra *mapextra // optional fields
}
Channel source structure:
type hchan struct {
qcount uint // total data in the queue
dataqsiz uint // size of the circular queue
buf unsafe.Pointer // points to an array of dataqsiz elements
elemsize uint16
closed uint32
elemtype *_type // element type
sendx uint // send index
recvx uint // receive index
recvq waitq // list of recv waiters
sendq waitq // list of send waiters
// lock protects all fields in hchan, as well as several
// fields in sudogs blocked on this channel.
//
// Do not change another G's status while holding this lock
// (in particular, do not ready a G), as this can deadlock
// with stack shrinking.
lock mutex
}
E.g:
package main
import "fmt"
func main() {
//map
fmt.Println("map:")
var nameId = make(map[string]int, 0)
fmt.Printf("nameId \ntype: %#v\n", nameId)
nameId["Golang"] = 1
nameId["C++"] = 2
nameId["PHP"] = 3
for name, id := range nameId {
fmt.Printf("name = %v, id = %v\n", name, id)
}
// slice
var hobby = make([]string, 2, 100) // 其中 2是长度,100是容量
hobby[0] = "打篮球"
hobby[1] = "乒乓球"
fmt.Println("\nslice:")
fmt.Printf("length = %v caps = %v\n", len(hobby), cap(hobby))
for _, name := range hobby {
fmt.Println(name)
}
// channel
ch := make(chan int, 3)
ch <- 1
ch <- 2
ch <- 8
close(ch)
fmt.Println("\nchannel:")
for val := range ch { // 遍历数据
fmt.Println(val)
}
}
Output:
[root@localhost test]# go run main.go
map:
nameId
type: map[string]int{}
name = Golang, id = 1
name = C++, id = 2
name = PHP, id = 3
slice:
length = 2 caps = 100
打篮球
乒乓球
channel:
1
2
8
[root@localhost test]#
Three, the difference between new and make
1. Both new and make are used to allocate memory;
2. Both new and make allocate memory on the heap;
3. New allocates memory for pointer types, and the return value is a pointer of allocation type. New cannot directly allocate memory for slice, map, and channel;
4. Make is only used for the initialization of slice, map and channel, and the return value is the type itself, not a pointer;