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

資訊專欄INFORMATION COLUMN

Golang什么時候該使用指針

社區管理員 / 794人閱讀

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

本文并不是標準更不是唯一答案,而是自己根據使用經驗和社區的一些討論而總結的實踐

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

type SliceHeader struct {
	Data uintptr
	Len  int
	Cap  int
}
  1. 結構體定義的字段

  2. 方法中接受者

  3. 函數傳參

  4. 函數和方法返回值

這里我先給出使用一般準則,后面詳細介紹不同場景的細節。

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

  • Slices,maps,channels,strings,function value and interface value 這些類型內部通過指針實現,再定一個指針指向這些類型的變量是多余的;

  • 當一個結構體很復雜或者需要修改結構體使用指針,其他情況使用值,因為濫用指針會出現一些不可預料的情況;

什么不需要使用指針


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


  • 值語義可以避免歧義,因為指針類型的賦值;

  • 犧牲干凈的語義換取速度并不是Golang所推薦的做法,有時值傳遞性能更好,因為值傳遞能夠避免緩存遺漏和隊分配;

  1. 對于切片,不需要使用指針指向它,仍然可以改變其元素,這是因為切片內部是通過指針指向底層數組實現的, 標準庫中io.Reader.Read(p []byte)函數中即通過傳遞值類型實現對切片 p 的修改。其實切片也可以當作是小型結構體,其定義如下, 在 64 位系統一個切片變量只占用 24 個字節。同樣地,對于 map 和 channel 類型,通常也不需要使用指針

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

什么時候必須使用指針

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

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

  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
    }

結構中定義

結構體中,除了需要考慮是否內存的占用之外,還需要考慮結構體的用途,一般主要分為工具結構體資源結構體, 資源結構體很容易理解,主要包括VO,DAO,Entity等,這類結構體一般用于模塊或分層之間的通信。對于這類結構體, 如用于序列化的結構體,根據序列化協議和庫可能有所區別,如Golang默認的Json序列化協議對于是否顯示字段, 定義為指針可以可好解決。下面是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定義為指針類型,就是為了序列化時更方便處理。 工具結構體通常指非資源結構體,主要是controller,config,factory和自定義數據結構類型, 這些結構體往往更需要考慮內存占用。

性能

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

以下兩個函數分別通過值拷貝和指針共享結構體:

分別進行進行基準測試:

執行基準測試,benchstat工具需要下載,鏈接為perf

image.png

可以看出,這時候通過值傳遞的方式執行更快,內存占用也更少。關于如何分析Golang程序和代碼段性能, 后續我會總結一篇博客多帶帶介紹。

總結

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


文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/127929.html

相關文章

  • golang學習筆記(一)——golang基礎和相關數據結構

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

    lyning 評論0 收藏0
  • golang 入門

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

    loonggg 評論0 收藏0
  • 對比學習:Golang VS Python3

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

    Jason 評論0 收藏0
  • 對比學習:Golang VS Python3

    摘要:在機器學習數據分析領域成為必學語言。不定長參數,支持不定長參數,用定義參數名,調用時多個參數將作為一個元祖傳遞到函數內返回函數結果。showImg(https://user-gold-cdn.xitu.io/2019/5/13/16ab0b937e7329d4); Golang和Python都是目前在各自領域最流行的開發語言之一。 Golang其高效而又友好的語法,贏得了很多后端開發人員的青...

    劉東 評論0 收藏0

發表評論

0條評論

社區管理員

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<