国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Golang什么時(shí)候該使用指針

社區(qū)管理員 / 777人閱讀

Golang 什么時(shí)候使用指針(Pointer)?什么時(shí)候使用值(Value)?對(duì)于go開發(fā)者來說是一件頭疼的事情, 而且這個(gè)問題似乎沒有絕對(duì)的答案,那是否代表我們可以隨意使用呢?答案當(dāng)然是否定的。本文我將試圖總結(jié)什么場景使用指針更合理。 在開始閱讀前,建議讀者先能夠清晰理解 Golang 指針、類型和值等概念。

本文并不是標(biāo)準(zhǔn)更不是唯一答案,而是自己根據(jù)使用經(jīng)驗(yàn)和社區(qū)的一些討論而總結(jié)的實(shí)踐

有下幾種情形,我們是否需要考慮使用指針:

type SliceHeader struct {
	Data uintptr
	Len  int
	Cap  int
}
  1. 結(jié)構(gòu)體定義的字段

  2. 方法中接受者

  3. 函數(shù)傳參

  4. 函數(shù)和方法返回值

這里我先給出使用一般準(zhǔn)則,后面詳細(xì)介紹不同場景的細(xì)節(jié)。

  • 方法通常使用指針作為接受者, 官方文檔的建議是:如果猶豫,請(qǐng)使用指針;

  • Slices,maps,channels,strings,function value and interface value 這些類型內(nèi)部通過指針實(shí)現(xiàn),再定一個(gè)指針指向這些類型的變量是多余的;

  • 當(dāng)一個(gè)結(jié)構(gòu)體很復(fù)雜或者需要修改結(jié)構(gòu)體使用指針,其他情況使用值,因?yàn)闉E用指針會(huì)出現(xiàn)一些不可預(yù)料的情況;

什么不需要使用指針


  1. CodeReviewComments中建議傳輸(pass)小型結(jié)構(gòu)體, 如type Point struct{ latitude,longtitude float64 },使用原始類型,除非需要修改它們,理由有以下幾點(diǎn)


  • 值語義可以避免歧義,因?yàn)橹羔橆愋偷馁x值;

  • 犧牲干凈的語義換取速度并不是Golang所推薦的做法,有時(shí)值傳遞性能更好,因?yàn)橹祩鬟f能夠避免緩存遺漏和隊(duì)分配;

  1. 對(duì)于切片,不需要使用指針指向它,仍然可以改變其元素,這是因?yàn)榍衅瑑?nèi)部是通過指針指向底層數(shù)組實(shí)現(xiàn)的, 標(biāo)準(zhǔn)庫中io.Reader.Read(p []byte)函數(shù)中即通過傳遞值類型實(shí)現(xiàn)對(duì)切片 p 的修改。其實(shí)切片也可以當(dāng)作是小型結(jié)構(gòu)體,其定義如下, 在 64 位系統(tǒng)一個(gè)切片變量只占用 24 個(gè)字節(jié)。同樣地,對(duì)于 map 和 channel 類型,通常也不需要使用指針

  2. 對(duì)于slices you'll reslice(更改其起始元素位置/長度/容量),如內(nèi)置函數(shù)func append(slice []Type, elems ...Type) []Type, 接受一個(gè)切片,返回新的切片。返回一個(gè)新數(shù)組會(huì)讓調(diào)用者更清晰地理解函數(shù)的語義。

什么時(shí)候必須使用指針

對(duì)于以下場景,使用指針是必須的:

  1. 如果結(jié)構(gòu)體中包含sync.Mutex獲取類似其他同步字段時(shí),由于這類字段類型是禁止拷貝的,所以無論其方法的接受者, 還是其作為參數(shù)和返回值都應(yīng)該使用指針:

  2. type FIFO struct {
    	lock sync.RWMutex
    	cond sync.Cond
    	items map[string]interface{}
    	queue []string
    	populated bool
    	initialPopulationCount int
    	keyFunc KeyFunc
    	closed bool
    }
    
    // Close the queue.
    func (f *FIFO) Close() {
    	f.lock.Lock()
    	defer f.lock.Unlock()
    	f.closed = true
    	f.cond.Broadcast()
    }
    
    // NewFIFO returns a Store which can be used to queue up items to
    // process.
    func NewFIFO(keyFunc KeyFunc) *FIFO {
    	f := &FIFO{
    		items:   map[string]interface{}{},
    		queue:   []string{},
    		keyFunc: keyFunc,
    	}
    	f.cond.L = &f.lock
    	return f
    }

結(jié)構(gòu)中定義

結(jié)構(gòu)體中,除了需要考慮是否內(nèi)存的占用之外,還需要考慮結(jié)構(gòu)體的用途,一般主要分為工具結(jié)構(gòu)體資源結(jié)構(gòu)體, 資源結(jié)構(gòu)體很容易理解,主要包括VO,DAO,Entity等,這類結(jié)構(gòu)體一般用于模塊或分層之間的通信。對(duì)于這類結(jié)構(gòu)體, 如用于序列化的結(jié)構(gòu)體,根據(jù)序列化協(xié)議和庫可能有所區(qū)別,如Golang默認(rèn)的Json序列化協(xié)議對(duì)于是否顯示字段, 定義為指針可以可好解決。下面是kubernetes IngressSpec的定義。

// IngressSpec describes the Ingress the user wishes to exist.
type IngressSpec struct {
	IngressClassName *string `json:"ingressClassName,omitempty" protobuf:"bytes,4,opt,name=ingressClassName"`
	Backend *IngressBackend `json:"backend,omitempty" protobuf:"bytes,1,opt,name=backend"`
	TLS []IngressTLS `json:"tls,omitempty" protobuf:"bytes,2,rep,name=tls"`
	Rules []IngressRule `json:"rules,omitempty" protobuf:"bytes,3,rep,name=rules"`
}

我們可以看到字段IngressClassName定義為指針類型,就是為了序列化時(shí)更方便處理。 工具結(jié)構(gòu)體通常指非資源結(jié)構(gòu)體,主要是controller,config,factory和自定義數(shù)據(jù)結(jié)構(gòu)類型, 這些結(jié)構(gòu)體往往更需要考慮內(nèi)存占用。

性能

使用指針并不是總能提升性能。使用指針可以避免值拷貝,減少棧內(nèi)存的占用,由于堆內(nèi)存的分配會(huì)導(dǎo)致GC頻繁地執(zhí)行,從而降低性能, 而值傳遞則不會(huì)。我們通過下面的實(shí)例Demo驗(yàn)證。

以下兩個(gè)函數(shù)分別通過值拷貝和指針共享結(jié)構(gòu)體:

分別進(jìn)行進(jìn)行基準(zhǔn)測試:

執(zhí)行基準(zhǔn)測試,benchstat工具需要下載,鏈接為perf

image.png

可以看出,這時(shí)候通過值傳遞的方式執(zhí)行更快,內(nèi)存占用也更少。關(guān)于如何分析Golang程序和代碼段性能, 后續(xù)我會(huì)總結(jié)一篇博客多帶帶介紹。

總結(jié)

本篇博文,簡單介紹怎樣如何使用指針更合理,其實(shí)很多場景都沒有標(biāo)準(zhǔn)答案,更多的是性能語義兩者的權(quán)衡。 掌握Golang中類型,值,指針類型等基礎(chǔ)概念才能優(yōu)雅地使用指針。遇到疑惑的參考標(biāo)準(zhǔn)庫中的實(shí)現(xiàn)和借鑒一些成熟的項(xiàng)目中的實(shí)踐;


文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/127929.html

相關(guān)文章

  • golang學(xué)習(xí)筆記(一)——golang基礎(chǔ)和相關(guān)數(shù)據(jù)結(jié)構(gòu)

    摘要:小白前端一枚,最近在研究,記錄自己學(xué)習(xí)過程中的一些筆記,以及自己的理解。此外,結(jié)構(gòu)體也支持嵌套。在函數(shù)聲明時(shí),在函數(shù)名前放上一個(gè)變量,這個(gè)變量稱為方法的接收器,一般是結(jié)構(gòu)體類型的。 小白前端一枚,最近在研究golang,記錄自己學(xué)習(xí)過程中的一些筆記,以及自己的理解。 go中包的依賴管理 go中的切片 byte 和 string go中的Map go中的struct結(jié)構(gòu)體 go中的方...

    lyning 評(píng)論0 收藏0
  • golang 入門

    摘要:而且數(shù)組是定長的,而切片可以調(diào)整長度。也就是說類型的值可以用于表示任意語言類型的值。下劃線讓編譯器接受這類導(dǎo)入,并且調(diào)用對(duì)應(yīng)包內(nèi)的所有代碼文件里定義的函數(shù)。結(jié)構(gòu)體可以當(dāng)做是一種數(shù)據(jù)類型一般都默認(rèn)函 緣起 之前下載視頻用的you-get,但是b站一直下不了,優(yōu)酷也經(jīng)常出問題,所以接觸到lulu https://github.com/iawia002/Lulu 這個(gè)也是基于you-get ...

    loonggg 評(píng)論0 收藏0
  • 對(duì)比學(xué)習(xí):Golang VS Python3

    摘要:和都是目前在各自領(lǐng)域最流行的開發(fā)語言之一。在機(jī)器學(xué)習(xí)數(shù)據(jù)分析領(lǐng)域成為必學(xué)語言。 showImg(https://segmentfault.com/img/remote/1460000019167290); Golang和Python都是目前在各自領(lǐng)域最流行的開發(fā)語言之一。 Golang其高效而又友好的語法,贏得了很多后端開發(fā)人員的青睞,最適用于高并發(fā)網(wǎng)絡(luò)編程的語言之一。 Python不...

    Jason 評(píng)論0 收藏0
  • 對(duì)比學(xué)習(xí):Golang VS Python3

    摘要:在機(jī)器學(xué)習(xí)數(shù)據(jù)分析領(lǐng)域成為必學(xué)語言。不定長參數(shù),支持不定長參數(shù),用定義參數(shù)名,調(diào)用時(shí)多個(gè)參數(shù)將作為一個(gè)元祖?zhèn)鬟f到函數(shù)內(nèi)返回函數(shù)結(jié)果。showImg(https://user-gold-cdn.xitu.io/2019/5/13/16ab0b937e7329d4); Golang和Python都是目前在各自領(lǐng)域最流行的開發(fā)語言之一。 Golang其高效而又友好的語法,贏得了很多后端開發(fā)人員的青...

    劉東 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<