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

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

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

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

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

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

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

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

理解角度:指針接收者可以選擇修改自己的值和不修改,值接收者修改自己的值是無效的(因?yàn)槭强截悾?。所以可以看成指針接收者的能?gt;值接收者的能力,自然:指針接收者實(shí)現(xiàn)某個(gè)方法可以看成值接收者實(shí)現(xiàn)某個(gè)方法,反之則不行。

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"} //運(yùn)行正常
    //上一行換成: var c coder = Gopher{"Go"} 
    // 則報(bào)錯(cuò) Gopher does not implement coder (debug method has pointer receiver)
    c.code()
    c.debug()
}

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

最佳實(shí)踐:

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

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

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

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

易錯(cuò)點(diǎn)辨析

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

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 ,說明沒有改值,因?yàn)榉椒ń邮照呤侵到邮照?

    someOnePtr := &Node{}
    someOnePtr.changeVal1()
    fmt.Printf("%d\n", someOnePtr.val) //0 ,說明沒有改值,因?yàn)榉椒ń邮照呤侵到邮照撸c調(diào)用方是否指針無關(guān)

    someTwo := Node{}
    someTwo.changeVal2()
    fmt.Printf("%d\n", someTwo.val) //1 ,說明成功改值,因?yàn)榉椒ń邮照呤侵羔樈邮照?,與調(diào)用方是否指針無關(guān)

    someTwoPtr := &Node{}
    someTwoPtr.changeVal2()
    fmt.Printf("%d\n", someTwoPtr.val) //1 ,說明成功改值,因?yàn)榉椒ń邮照呤侵羔樈邮照?,與調(diào)用方是否指針無關(guān)

}

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

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

相關(guān)文章

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

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

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

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

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

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

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

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

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

    goland安裝1.7版本報(bào)錯(cuò)Unpacked?SDK?is?corrupted解決

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

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

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

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

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

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

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

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

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

    go中import包的大坑解決方案

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

最新評(píng)論