目錄
一、new
二、make
三、new 和 make的區別
許多小伙伴在剛接觸 Golang 的時候不理解為什么會有兩個用于分配記憶體的函式: new 和 make,俗話說:存在即合理,下面就來詳細說明下這兩者的區別,
一、new
先看函式宣告:
func new(Type) *Type
new 是 Golang 的內建函式,用于分配記憶體,其中,第一個引數是型別,回傳值是型別的指標,其值被初始化為“零”(型別對應的零值,int 初始化為0,bool初始化為 false 等),
例如:
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)
}
輸出:
id type: *int value: 0
name type: *string value:
flag type: *bool value: false
從上述例子可以看到,初始化的“零”值根據型別不同而不同,整數初始化為 0,字串初始化為空,bool型別初始化為 false,
二、make
先看函式宣告:
func make(t Type, size ...IntegerType) Type
make 是 Golang 的內建函式,僅用于分配和初始化 slice、map 以及 channel 型別的物件,三種型別都是結構,回傳值為型別,而不是指標,
slice 原始碼結構:
type slice struct {
array unsafe.Pointer //指標
len int //長度
cap int //容量
}
map 原始碼結構:
// 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 原始碼結構:
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
}
例如:
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)
}
}
輸出:
[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]#
三、new 和 make的區別
1. new 和 make 都用于分配記憶體;
2. new 和 make 都是在堆上分配記憶體;
3. new 對指標型別分配記憶體,回傳值是分配型別的指標,new不能直接對 slice 、map、channel 分配記憶體;
4. make 僅用于 slice、map和 channel 的初始化,回傳值為型別本身,而不是指標;
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/240869.html
標籤:區塊鏈
