關(guān)鍵點(diǎn)
1募壕、
分配內(nèi)存
的內(nèi)置函數(shù)是new
和make
2南蓬、new 方式 分配內(nèi)存纺非,
并不常用
,一般使用短式和結(jié)構(gòu)體字面量
的方式3蓖康、new 不能用于
map
铐炫,channel
垒手,切片
的聲明4蒜焊、
new 分配
時(shí),接收
的是類型
科贬,返回的是該類型的指針
泳梆,并且默認(rèn)
? ?初始化
了5、
make 分配
后榜掌,沒(méi)有初始化
优妙,需要顯示初始化
6、make 分配內(nèi)存后憎账,返還的是該
類型
7套硼、make的使用場(chǎng)景
? 下面三個(gè)進(jìn)行聲明
和初始化
時(shí)用
channel
切片
map
8胞皱、sync.Map, 以及 sync.Mutex 這兩個(gè)可以直接 通過(guò)var來(lái)聲明變量邪意,
不需要 初始化
var map2 sync.Map
var mu sync.Mutex,
? ?可以直接使用map2, mu變量反砌,操作
9雾鬼、普通變量,聲明后宴树,
就有默認(rèn)的初始化值
,可以直接
使用10策菜、引用類型,需要
聲明
酒贬、分配內(nèi)存
兩步又憨;如果只是
聲明,操作時(shí)會(huì)拋異常
1锭吨、前言
本文主要給大家介紹了Go語(yǔ)言中函數(shù)new與make的使用和區(qū)別蠢莺,
關(guān)于Go語(yǔ)言中new和make是內(nèi)建的兩個(gè)函數(shù),主要用來(lái)創(chuàng)建分配類型內(nèi)存耐齐。
在我們定義生成變量的時(shí)候浪秘,可能會(huì)覺得有點(diǎn)迷惑蒋情,其實(shí)他們的規(guī)則很簡(jiǎn)單,
下面我們就通過(guò)一些示例說(shuō)明他們的區(qū)別和使用耸携,話不多說(shuō)了棵癣,來(lái)一起看看詳細(xì)的介紹吧。
2夺衍、變量的聲明
var I int
var s string
變量的聲明
我們可以通過(guò)var關(guān)鍵字
狈谊,然后就可以在程序中使用。
當(dāng)我們不指定變量的默認(rèn)值時(shí)沟沙,這些變量的默認(rèn)值是他們的零值河劝,
比如int類型的零值是0,string類型的零值是"",引用類型的零值是nil矛紫。
對(duì)于例子中的兩種類型的聲明赎瞎,我們可以直接使用,對(duì)其進(jìn)行賦值輸出颊咬。
但是如果我們換成引用類型呢?
package main
import (
"fmt"
)
func main() {
var i *int
*I=10
fmt.Println(*i)
}
從這個(gè)提示中可以看出务甥,對(duì)于引用類型的變量
,我們不光要聲明
它喳篇,還要為它分配內(nèi)寸空間
敞临,否則我們的值放在哪里去呢
?
這就是上面錯(cuò)誤提示的原因麸澜。
對(duì)于值類型的聲明不需要
挺尿,是因?yàn)橐呀?jīng)默認(rèn)幫我們分配好了
。
要分配內(nèi)存炊邦,就引出來(lái)今天的new和make编矾。
3、new 方式
對(duì)于上面的問(wèn)題我們?nèi)绾谓鉀Q呢铣耘?
既然我們知道了沒(méi)有為其分配內(nèi)存洽沟,那么我們使用new分配一個(gè)吧。
func main() {
var i *int
i=new(int)
*I=10
fmt.Println(*i)
}
現(xiàn)在再運(yùn)行程序蜗细,完美PASS裆操,打印10。
現(xiàn)在讓我們看下new這個(gè)內(nèi)置的函數(shù)炉媒。
// The new built-in function allocates memory. The first argument is a type,
// not a value, and the value returned is a pointer to a newly
// allocated zero value of that type.
func new(Type) *Type
它只接受一個(gè)參數(shù)踪区,這個(gè)參數(shù)是一個(gè)類型
,分配好內(nèi)存后吊骤,返回一個(gè)指向該類型內(nèi)存地址的指針
缎岗。
同時(shí)請(qǐng)注意它同時(shí)把分配的內(nèi)存置為零
,也就是類型的零值
白粉。
我們的例子中传泊,如果沒(méi)有*i=10鼠渺,那么打印的就是0。
這里體現(xiàn)不出來(lái)new函數(shù)這種內(nèi)存置為零的好處眷细,我們?cè)倏匆粋€(gè)例子拦盹。
package main
import (
"sync"
"fmt"
)
type user struct {
lock sync.Mutex
name string
age int
}
func main() {
u := new(user)
u.lock.Lock()
u.name = "張三"
u.lock.Unlock()
fmt.Println(u)
}
示例中的user類型中的lock字段我
不用初始化
,直接
可以拿來(lái)用
溪椎,
不會(huì)
有無(wú)效內(nèi)存
引用異常
普舆,因?yàn)樗呀?jīng)被零值
了。
這就是new校读,它返回的永遠(yuǎn)是類型的指針
沼侣,指向分配類型的內(nèi)存地址
。
4歉秫、make 方式
make也是用于
內(nèi)存分配
的蛾洛,但是和new不同,它只用于
chan端考、map以及切片的內(nèi)存創(chuàng)建
雅潭,而且它返回的類型就是這三個(gè)
類型本身
,-
而不是他們的指針類型却特,
- 因?yàn)檫@三種類型就是
引用類型
,所以就沒(méi)有必要
返回他們的指針
了筛圆。
- 因?yàn)檫@三種類型就是
注意裂明,因?yàn)檫@三種類型是引用類型
,所以必須
得初始化
太援,
但是不是置為零值闽晦,這個(gè)和new是不一樣的。
func make(t Type, size ...IntegerType) Type
從函數(shù)聲明中可以看到提岔,返回的還是該類型
仙蛉。
5、new 與 make的不同點(diǎn)
所以從這里可以看的很明白了碱蒙,二者都是內(nèi)存的分配(堆上)
荠瘪,
但是make只用于slice、map以及channel的初始化(非零值)
赛惩;
而new用于類型的內(nèi)存分配
哀墓,并且內(nèi)存置為零
。
所以在我們編寫程序的時(shí)候喷兼,就可以根據(jù)自己的需要很好的選擇了篮绰。
make返回的還是這三個(gè)引用類型本身;
而new返回的是指向類型的指針
季惯。
6吠各、其實(shí)new 不常用
所以有new這個(gè)內(nèi)置函數(shù)臀突,可以給我們分配一塊內(nèi)存讓我們使用,
但是現(xiàn)實(shí)的編碼中贾漏,它是不常用的
惧辈。
我們通常都是采用短語(yǔ)句聲明
以及結(jié)構(gòu)體的字面量
達(dá)到我們的目的,
比如:
I:=0
u:=user{}
這樣更簡(jiǎn)潔方便磕瓷,而且不會(huì)涉及到指針這種比麻煩的操作盒齿。
make函數(shù)是無(wú)可替代的,我們?cè)谑褂胹lice困食、map以及channel的時(shí)候边翁,
還是要使用make進(jìn)行初始化
,然后才才可以對(duì)他們進(jìn)行操作硕盹。