欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

go 指針接收者和值接收者的區(qū)別小結(jié)

 更新時間:2025年04月17日 11:30:46   作者:思無邪_  
在Go 語言中,值接收者和指針接收者是方法定義中的兩種接收者類型,本文主要介紹了go 指針接收者和值接收者的區(qū)別小結(jié),文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

go 指針接收者和值接收者的區(qū)別

指針接收者和值接收者的區(qū)別主要有兩點:

  • Go 中函數(shù)傳參是傳值,因此指針接收者傳遞的是接收者的指針拷貝,值接收者傳遞的是接收者的拷貝---在方法中指針接收者的變量會被修改,而值接收者的成員變量修改是無效的(畢竟傳入的是拷貝,修改的自然也是拷貝的成員變量)。
  • 在接口實現(xiàn)上,如果值接收者實現(xiàn)了某個方法,相當(dāng)于值接收者和指針接收者都實現(xiàn)了這個方法。反之則不行,即指針接收者實現(xiàn)了某個方法,不能看成值接收者實現(xiàn)這個方法。

注意第2點只影響接口實現(xiàn),如果不涉及接口的話是不受到這條規(guī)則約束的。

一個助記的但是不太正確的觀點:接收者是指針類型的方法,很可能在方法中會對接收者的屬性進(jìn)行更改操作,從而影響接收者;而對于接收者是值類型的方法,在方法中不會對接收者本身產(chǎn)生影響。

理解角度:指針接收者可以選擇修改自己的值和不修改,值接收者修改自己的值是無效的(因為是拷貝)。所以可以看成指針接收者的能力>值接收者的能力,自然:指針接收者實現(xiàn)某個方法可以看成值接收者實現(xiàn)某個方法,反之則不行。

package main

import "fmt"

type coder interface {
    code()
    debug()
}

type Gopher struct {
    language string
}

func (p Gopher) code() {
    fmt.Printf("I am coding %s language\n", p.language)
}

func (p *Gopher) debug() {
    fmt.Printf("I am debuging %s language\n", p.language)
}

func main() {
    var c coder = &Gopher{"Go"} //運行正常
    //上一行換成: var c coder = Gopher{"Go"} 
    // 則報錯 Gopher does not implement coder (debug method has pointer receiver)
    c.code()
    c.debug()
}

注意??:對于????上面的第 2 點補(bǔ)充:雖然隱式實現(xiàn)的方法不一樣,但是如果不涉及接口,單純在調(diào)用的時候,無論是指針接收者還是值接收者實現(xiàn)了某個方法,指針接收者和值接收者都可以調(diào)用。本質(zhì)上是 go 的語法糖。

最佳實踐:

如果類型具備“原始的本質(zhì)”,即其成員都是由 Go 語言里內(nèi)置的原始類型,如字符串,整型值等,那就定義值接收者類型的方法。

內(nèi)置的引用類型,如 slice,map,interface,channel,這些類型比較特殊,聲明他們的時候,實際上是創(chuàng)建了一個 header?, 對于他們也是直接定義值接收者類型的方法。這樣,調(diào)用函數(shù)時,是直接 copy 了這些類型的 header?,而 header? 本身就是為復(fù)制設(shè)計的。

如果類型具備非原始的本質(zhì),不能被安全地復(fù)制,這種類型總是應(yīng)該被共享,那就定義指針接收者的方法。

雖然上面是這么說,但是個人感覺在實際使用中,基本可以無腦使用指針接收者。主要原因在于:1.指針接收者沒有值拷貝帶來的巨大開銷。2.如果就想在函數(shù)中修改值就必須使用指針接收者。3.值接收者唯一的優(yōu)勢就是為了防止意外的修改,為了防止這一點可以通過創(chuàng)建一個函數(shù)或者方法來手動 copy,而這并不會帶來多大的開銷。

易錯點辨析

是否改變結(jié)構(gòu)體的值看的是方法是指針接收者還是值接收者,而不是看調(diào)用方是指針還是值。原因在于golang編譯器在背后會完成一些工作,比如:解引用,隱式使用引用。代碼范例如下:

package main

import "fmt"

type Node struct {
    val int
}

func (receiver Node) changeVal1() {
    receiver.val++
}

func (receiver *Node) changeVal2() {
    receiver.val++
}
func main() {
    someOne := Node{}
    someOne.changeVal1()
    fmt.Printf("%d\n", someOne.val) //0 ,說明沒有改值,因為方法接收者是值接收者

    someOnePtr := &Node{}
    someOnePtr.changeVal1()
    fmt.Printf("%d\n", someOnePtr.val) //0 ,說明沒有改值,因為方法接收者是值接收者,與調(diào)用方是否指針無關(guān)

    someTwo := Node{}
    someTwo.changeVal2()
    fmt.Printf("%d\n", someTwo.val) //1 ,說明成功改值,因為方法接收者是指針接收者,與調(diào)用方是否指針無關(guān)

    someTwoPtr := &Node{}
    someTwoPtr.changeVal2()
    fmt.Printf("%d\n", someTwoPtr.val) //1 ,說明成功改值,因為方法接收者是指針接收者,與調(diào)用方是否指針無關(guān)

}

參考:https://golang.design/go-questions/interface/receiver/

到此這篇關(guān)于go 指針接收者和值接收者的區(qū)別小結(jié)的文章就介紹到這了,更多相關(guān)go 指針接收者和值接收者內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • go語言代碼生成器code?generator使用示例介紹

    go語言代碼生成器code?generator使用示例介紹

    這篇文章主要為大家介紹了go語言代碼生成器code?generator的使用簡單介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • 使用Go實現(xiàn)優(yōu)雅重啟服務(wù)功能

    使用Go實現(xiàn)優(yōu)雅重啟服務(wù)功能

    這篇文章主要介紹了如何使用Go來實現(xiàn)優(yōu)雅重啟服務(wù),本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-11-11
  • 淺析Golang中的協(xié)程(goroutine)

    淺析Golang中的協(xié)程(goroutine)

    在Go語言中,協(xié)程(goroutine)是輕量級的線程,它是Go語言中實現(xiàn)并發(fā)編程的基礎(chǔ),Go語言中的協(xié)程是由Go運行時調(diào)度器(scheduler)進(jìn)行管理和調(diào)度的,本文將給大家簡單的介紹一下Golang中的協(xié)程,需要的朋友可以參考下
    2023-05-05
  • 詳解prometheus監(jiān)控golang服務(wù)實踐記錄

    詳解prometheus監(jiān)控golang服務(wù)實踐記錄

    這篇文章主要介紹了詳解prometheus監(jiān)控golang服務(wù)實踐記錄,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • goland安裝1.7版本報錯Unpacked?SDK?is?corrupted解決

    goland安裝1.7版本報錯Unpacked?SDK?is?corrupted解決

    這篇文章主要為大家介紹了goland安裝1.7版本報錯Unpacked?SDK?is?corrupted解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • Go結(jié)合Redis用最簡單的方式實現(xiàn)分布式鎖

    Go結(jié)合Redis用最簡單的方式實現(xiàn)分布式鎖

    本文主要介紹了Go結(jié)合Redis用最簡單的方式實現(xiàn)分布式鎖示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • golang time包做時間轉(zhuǎn)換操作

    golang time包做時間轉(zhuǎn)換操作

    這篇文章主要介紹了golang time包做時間轉(zhuǎn)換操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Golang基礎(chǔ)之函數(shù)使用(參數(shù)傳值)實例詳解

    Golang基礎(chǔ)之函數(shù)使用(參數(shù)傳值)實例詳解

    這篇文章主要為大家介紹了Golang基礎(chǔ)之函數(shù)使用(參數(shù)傳值)實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • 在Golang中讀寫CSV文件的操作指南

    在Golang中讀寫CSV文件的操作指南

    CSV(逗號分隔值)文件是一種常見的數(shù)據(jù)存儲格式,廣泛應(yīng)用于數(shù)據(jù)導(dǎo)入、導(dǎo)出、分析和交換等場景,在Golang中,有許多庫和工具可以幫助我們讀取和寫入CSV文件,使數(shù)據(jù)處理變得簡單而高效,本文將深入探討如何在Golang中使用標(biāo)準(zhǔn)庫以及第三方庫來讀寫CSV文件
    2023-11-11
  • go中import包的大坑解決方案

    go中import包的大坑解決方案

    最近開始使用Go/GoLand 在import 自定義包時出現(xiàn)各種狀況,本文就介紹一下go中import包的大坑解決方案,具有一定的參考價值,感興趣 可以了解一下
    2022-06-06

最新評論