最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go方法接收者值接收者與指針接收者詳解

 更新時間:2022年11月02日 16:22:14   作者:大愚Talk  
這篇文章主要為大家介紹了Go方法接收者值接收者與指針接收者詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

在review 一些代碼中,發(fā)現(xiàn)經(jīng)常某個類型定義的方法,其接收者既有值類型,又有指針類型,然后 Goland 就有提示: Struct Person has methods on both value and pointer receivers. Such usage is not recommended by the Go Documentation.

一般來講,這個提示對代碼的運行并不會產(chǎn)生什么問題。只不過對于有輕微 “代碼潔癖” 的人來講,體感不好,就一定想要改統(tǒng)一。

當然,我并不是想講要統(tǒng)一的問題,前面說這么多廢話,只是為了鋪墊一下引出本文的內(nèi)容:Go中的值接收者與指針接收者有什么關(guān)系與區(qū)別,該怎么選?

聯(lián)系與區(qū)別

在繼續(xù)講下去之前,我們得先明確,Go 里邊能夠定義方法的必須是自定義類型,而不能是系統(tǒng)內(nèi)置類型,比如 int、string 這種是不可以為其添加方法的。

那么當我們定義了一個自定義類型,可以為其添加方法,先上代碼:

package main
import "fmt"
type Person struct {
   name string
   age  int
}
// 值針接收者
func (p Person) GetName() string {
   return p.name
}
// 指針接收者
func (p *Person) GetAge() int {
   return p.age
}
func main() {
   //  定義了一個【值類型】
   t := Person{
      name: "DaYu",
      age:  int(28),
   }
   // 調(diào)用值方法
   fmt.Println(t.GetName())
   // 調(diào)用指針方法
   fmt.Println(t.GetAge())
}
-----運行結(jié)果-------
study/demo01/client go run *
DaYu
28

指針類型調(diào)用結(jié)果

從使用過程看,值類型的變量,可以調(diào)用該類型的值接收者方法,也可以調(diào)用指針接收者方法。

反之,我們可以定義一個指針類型,然后看看調(diào)用結(jié)果:

package main
import "fmt"
type Person struct {
   name string
   age  int
}
func (p *Person) GetName() string {
   return p.name
}
func (p Person) GetAge() int {
   return p.age
}
func main() {
   // 注意,其它地方都沒有改,只是這里改變了類型
   t := &Person{
      name: "DaYu",
      age:  int(28),
   }
   fmt.Println(t.GetName())
   fmt.Println(t.GetAge())
}
-----運行結(jié)果-------
study/demo01/client go run *
DaYu
28

這段代碼告訴我們,指針類型的變量,可以調(diào)用該類型的值接收者方法,也可以調(diào)用指針接收者方法。

是不是特別有意思?

  • 值類型變量,可以調(diào)用值接收的方法,也可以調(diào)用指針接收者的方法;
  • 指針類型變量,可以調(diào)用值接收的方法,也可以調(diào)用指針接收者的方法。

看起來好像兩者對等的,并沒有差別。那么二者真的沒有差別嗎?只是一種表達形式上的差異?其實不然,如果引入接口類型后,我們再來看看。

package main
// 新增的接口
type Animal interface {
   GetName() string
   GetAge() int
}
type Person struct {
   name string
   age  int
}
func (p *Person) GetName() string {
   return p.name
}
func (p Person) GetAge() int {
   return p.age
}
func main() {
   // 定義的接口變量
   var ani Animal
   // person 實現(xiàn)了 Animal 接口,賦值給了 ani 變量
   // 但是,這里編譯會通不過,錯誤如下:
   // Cannot use 'Person{ name: "DaYu", age: int(28), }' (type Person) as the type Animal Type does not implement 'Animal' as the 'GetName' method has a pointer receiver
   ani = Person{
      name: "DaYu",
      age:  int(28),
   }
   ani.GetName()
   ani.GetAge()
}

為什么會報錯呢? 錯誤提醒很明顯了:Person 沒有實現(xiàn) Animal 的 GetName 方法。因為在上面的代碼中,我們實現(xiàn) GetName 方法的是 (*Person) 類型。

但是為什么 GetAge 方法不報錯呢? 那是因為 Go 里邊對于 (Type)Method 的方法,會自動讓他擁有 (*Type)Method 方法的能力。

實現(xiàn)接口時約束

  • 如果定義的是 (Type)Method,則該類型會隱式的聲明一個 (*Type)Method;
  • 如果定義的是 (*Type)Method ,則不會隱式什么一個 (Type)Method。

至于為什么不也隱式申明一個 (Type)Method ,我覺得有一個原因是,我們一般采用指針接收者時,方法內(nèi)部改變的值,接收者本身也會改變,那么此時如果隱式有這樣一個申明,外部使用值類型時,這個改變就不會生效,語義上就會非常奇怪。

該怎么用

從使用表現(xiàn)上看,指針接收者在方法內(nèi)部的改變,會體現(xiàn)到其本身。但這并不是決定我們要不要用指針接收者的唯一理由! 最重要的還是看接收者要不要全局共享一個實體,其次某些場景下,如果接收者本身太大,拷貝成本很高,也應該使用指針接收者。

回到文檔開篇的問題,為什么不建議值接收者、指針接收者混用,主要還是在于語義不夠清晰,存在潛在理解成本的問題。

以上就是Go方法接收者值接收者與指針接收者詳解的詳細內(nèi)容,更多關(guān)于Go方法值接收者指針接收者的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 分析Go錯誤處理優(yōu)化go?recover機制缺陷

    分析Go錯誤處理優(yōu)化go?recover機制缺陷

    這篇文章主要為大家介紹了分析Go錯誤處理優(yōu)化go?recover機制缺陷示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • Go語言實現(xiàn)Base64、Base58編碼與解碼

    Go語言實現(xiàn)Base64、Base58編碼與解碼

    本文主要介紹了Base64、Base58編碼與解碼,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Go語言時間處理必備技巧全解析

    Go語言時間處理必備技巧全解析

    Golang 的時間處理是 Golang 編程中的一個重要方面,它涉及到了時間類型、時間格式化、時間計算、時區(qū)處理以及定時器和超時機制等多個方面。在本文中,我們將從更深入的角度來探討 Golang 的時間處理
    2023-04-04
  • Go語言七篇入門教程四通道及Goroutine

    Go語言七篇入門教程四通道及Goroutine

    這篇文章主要為大家介紹了Go語言的通道及Goroutine示例詳解,本文是Go語言七篇入門系列篇,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-11-11
  • Golang測試func?TestXX(t?*testing.T)的使用詳解

    Golang測試func?TestXX(t?*testing.T)的使用詳解

    一般Golang中的測試代碼都以xxx_test.go的樣式,在命名測試函數(shù)的時候以Testxx開頭,下面給大家介紹Golang測試func?TestXX(t?*testing.T)的使用,感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • Golang程序中使用Prometheus的client_golang庫

    Golang程序中使用Prometheus的client_golang庫

    這篇文章主要介紹了Golang程序中使用Prometheus的client_golang庫,Prometheus 是一個開源的監(jiān)控和警報工具包,用于收集和處理應用程序和系統(tǒng)的指標數(shù)據(jù)。Prometheus 提供了多種客戶端庫,可以輕松地集成到各種編程語言中
    2023-04-04
  • 對Golang中的FORM相關(guān)字段理解

    對Golang中的FORM相關(guān)字段理解

    這篇文章主要介紹了對Golang中的FORM相關(guān)字段理解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • Golang實現(xiàn)JWT身份驗證的示例詳解

    Golang實現(xiàn)JWT身份驗證的示例詳解

    JWT(JSON Web Token)是一種開放標準(RFC 7519),用于在網(wǎng)絡應用間安全地傳輸聲明,本文主要為大家詳細介紹了Golang實現(xiàn)JWT身份驗證的相關(guān)方法,希望對大家有所幫助
    2024-03-03
  • 詳解go-zero如何實現(xiàn)計數(shù)器限流

    詳解go-zero如何實現(xiàn)計數(shù)器限流

    這篇文章主要來和大家說說限流,主要包括計數(shù)器限流算法以及具體的代碼實現(xiàn),文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-08-08
  • Golang線上內(nèi)存爆掉問題排查(pprof)與解決

    Golang線上內(nèi)存爆掉問題排查(pprof)與解決

    這篇文章主要介紹了Golang線上內(nèi)存爆掉問題排查(pprof)與解決,涉及到數(shù)據(jù)敏感,文中代碼是我模擬線上故障的一個情況,好在我們程序都有添加pprof監(jiān)控,于是直接通過go tool pprof分析,需要的朋友可以參考下
    2024-04-04

最新評論

五莲县| 平利县| 广河县| 长武县| 华池县| 彩票| 象山县| 天祝| 化州市| 鄂托克旗| 来凤县| 四会市| 宾阳县| 革吉县| 内江市| 独山县| 阳江市| 阿巴嘎旗| 云林县| 宾阳县| 容城县| 日喀则市| 滨州市| 安义县| 闻喜县| 崇信县| 平和县| 天柱县| 淅川县| 堆龙德庆县| 班戈县| 南昌县| 开阳县| 榆树市| 韩城市| 黄浦区| 兴义市| 穆棱市| 嘉善县| 西华县| 喀什市|