GO 語(yǔ)言的方法??

GO 中的方法是什么?

前面我們有分享到 GO 語(yǔ)言的函數(shù),他是一等公民,那么 GO 語(yǔ)言中的方法和函數(shù)有什么區(qū)別呢?

GO 語(yǔ)言中的方法實(shí)際上和函數(shù)是類似的,只不過(guò)在函數(shù)的基礎(chǔ)上多了一個(gè)參數(shù),這個(gè)參數(shù)在 GO 語(yǔ)言中被稱為 receiver 參數(shù)

例如我們可以這么來(lái)申明一個(gè)方法:

func (xx T/*T) helloworld(入?yún)?shù)列表) (返回值列表) {
    // 具體實(shí)現(xiàn)
}

demo 中的 helloworld 方法就綁定到了 receiver T 類型上,這個(gè) helloworld 方法,我們可以通過(guò)使用 T 類型或者 *T 來(lái)進(jìn)行調(diào)用,例如:

var tt T
tt.helloworld(入?yún)?shù)列表)
var pt *T
pt.helloworld(入?yún)?shù)列表)

看著還是挺簡(jiǎn)單的對(duì)嗎?對(duì)于使用的時(shí)候我們需要注意這些問(wèn)題:

  1. GO 語(yǔ)言中原生的類型,是不能作為上述的 receiver 的,例如 int,slice,map等等都是不行的,只能是我們自定義的類型
  2. 方法只能有一個(gè) receiver 參數(shù),只能綁定一個(gè),不能綁定多個(gè)
  3. receiver 參數(shù)類型本身不能是指針或者是接口類型,這里非常需要注意

如圖:receiver 參數(shù)類型本身不能是指針類型

[圖片上傳失敗...(image-15295b-1697727234624)]

如圖:receiver 參數(shù)類型本身不能是接口類型

[圖片上傳失敗...(image-fe9a1a-1697727234625)]

對(duì)于方法,是綁定了一個(gè) receiver 類型的參數(shù),那么這個(gè)參數(shù)是不是很像 C++ 里面的入?yún)⒛兀?/p>

func helloworld(xx T/*T, 其他入?yún)? (返回值列表){
    // 具體實(shí)現(xiàn)
}

所以在 GO 語(yǔ)言里面,我們能夠明白一個(gè)方法所綁定類型的實(shí)例,實(shí)際上就是一個(gè)普通函數(shù)的第一個(gè)參數(shù)

就像這樣

func (t T) helloworld()  ==  helloworld(t T)
func (pt *T) helloworld()  ==  helloworld(pt *T)

那么,對(duì)于上述綁定的類型,有 T 也有 *T ,如何去選擇呢?什么時(shí)候用 T 什么時(shí)候又用 *T 呢?

此處 T 叫做值類型 , *T 叫做指針類型 ,選擇不同的類型,

  1. 如果選擇 T 類型,那么這是一個(gè)值傳遞類型的,在調(diào)用 helloworld 方法的時(shí)候,實(shí)際上就是傳了一個(gè) T 類型實(shí)例的副本,那么如果在 helloworld 方法中對(duì) t 做了一些變動(dòng),那么只會(huì)影響副本,對(duì)于原來(lái)的 T 類型實(shí)例,是不會(huì)有影響的
  2. 如果選擇了 T 類型,那么這就是一個(gè)指針類型的,調(diào)用 helloworld 方法的時(shí)候,傳的就是類型 T 的實(shí)例地址,這個(gè)時(shí)候 helloworld 內(nèi)部如果對(duì) t 做了一些變動(dòng),都會(huì)體現(xiàn)到原來(lái)的 T 的實(shí)例上*

這個(gè)理解方式實(shí)際上就和咱們普通函數(shù)中傳入的參數(shù)是一樣的,傳值和傳地址的區(qū)別

一個(gè)簡(jiǎn)單的 demo ,再來(lái)加深一下:

  1. 定義個(gè) TT 類型的結(jié)構(gòu),成員有 Name
  2. 定義 Hello1 方法綁定 TT,定義 hello2 方法綁定 *TT
  3. 新建一個(gè) TT 類型的變量 t,分別去調(diào)用 hello1 和 hello2
  4. 新建一個(gè) *TT 類型的變量 pt,分別去調(diào)用 hello1 和 hello2

[圖片上傳失敗...(image-f78f18-1697727234625)]

可以看到上述程序的結(jié)果如下:

name ==
name ==  hello2
name ==
name ==  hello2

從上述 demo 中就可以看出,實(shí)際上 GO 語(yǔ)言對(duì)于我們調(diào)用方法的時(shí)候是做了隱式轉(zhuǎn)換,無(wú)論是值類型的實(shí)例,還是指針類型的實(shí)例,都是可以去調(diào)用綁定了值類型的方法,也可以去調(diào)用綁定了指針類型的方法

只不過(guò)得到的結(jié)果,就要看具體方法是綁定的值類型,還是指針類型了

所以我們?nèi)绾稳ミx擇 receiver 的類型到此就很清楚了吧?

如果我們期望要去修改 receiver 類型的實(shí)例,那么就用指針類型,如果不期望修改,則使用值類型

當(dāng)然,如果我們是要考慮到性能,就要使用傳地址的方式較好

方法的集合

GO 里面雖然沒(méi)有類,沒(méi)有對(duì)象,沒(méi)有繼承,但是關(guān)于面向?qū)ο罄锩娴膬?nèi)容在 GO 里面完全可以使用組合的方式來(lái)進(jìn)行實(shí)現(xiàn)

所以對(duì)于GO 里面是如何組合的的基本知識(shí)我們要搞清楚,前提我們就先要弄明白方法的集合是如何玩的

在 GO 語(yǔ)言里面,我們?cè)诮o接口變量復(fù)制,使用結(jié)構(gòu)體嵌入或者接口嵌入,使用 類型別名的時(shí)候,都是會(huì)涉及到方法集合的,但是具體要看某一個(gè)實(shí)例包含哪些方法集合,我們就可以來(lái)演練一下

  1. 定義 ITT 接口,里面有 2 個(gè)方法 Hello1() , Hello2()
  2. 定義 TT 結(jié)構(gòu)體,實(shí)現(xiàn)上述接口,其中 Hello1() 綁定 TT , Hello2() 綁定 *TT
  3. 查看 nil 轉(zhuǎn)成 ITT 的方法集合,TT 的方法集合,*TT 的方法集合
type ITT interface{
   Hello1()
   Hello2()

}

type TT struct{}

func (t TT)Hello1(){}

func (pt *TT)Hello2(){}

// 打印方法集合
func GetMethodSet(i interface{}){
   v := reflect.TypeOf(i)
   et := v.Elem()
    num := et.NumMethod()
    if num == 0 {
      fmt.Println(et, "methond num is 0" )
      return
    }
   // 有方法集合
   fmt.Println(et,"mthond set is :")
   for i:=0;i<num;i++{
      fmt.Println("---",et.Method(i).Name)
   }
}


func main(){
   var t TT
   var pt * TT
   // 先查看 nil 接口的方法集合
   GetMethodSet((*ITT)(nil))
   // 查看 TT 的方法集合
   GetMethodSet(&t)
   // 查看 *TT 的方法集合
   GetMethodSet(&pt)
}

運(yùn)行結(jié)果如下:

[圖片上傳失敗...(image-4b517a-1697727234625)]

可以查看到上述案例,綁定類型為 TT 的,方法集合只有 1 個(gè),綁定類型為 *TT 的方法集合有 2 個(gè),可以看得出來(lái)

**T 類型的方法集合是包含了 T 類型和 T 類型

T 類型的方法集合是包含了 T 類型

對(duì)于 GO 語(yǔ)言里面的組合,總的來(lái)說(shuō)有三種,這個(gè)可以多多嘗試和寫(xiě) demo 練習(xí):

  1. 接口中嵌入接口
type ITT interface{
    hello1()
}
type ITT2 interface{
    hello2()
}
type ITT3 interface{
    ITT 
    ITT2 
}

接口中嵌入接口,最終的接口方法個(gè)數(shù)是取和數(shù),此處我們要注意的地方就是方法名如果重復(fù),也是可以正常得到方法集合,具體使用接口中的方法,還是要看實(shí)例是如何實(shí)現(xiàn)的

  1. 結(jié)構(gòu)體中嵌入接口
type ITT interface{
    hello1()
    hello2()
}
type ITT2 interface{
    hello2()
    hello3()
}
type TT struct{
    ITT 
    ITT2
}
// 此時(shí) TT  的方法集合就存在 hello2() 是沖突的,因此此處就需要 TT 去實(shí)現(xiàn)自己的 hello2()
func (TT)hello2(){}

結(jié)構(gòu)體中嵌入接口,如果遇到同名的方法,GO 語(yǔ)言會(huì)優(yōu)先選擇結(jié)構(gòu)體自己實(shí)現(xiàn)的方法,如果結(jié)構(gòu)體自己未實(shí)現(xiàn),則會(huì)將接口中的同名方法提升到自己的結(jié)構(gòu)體中來(lái)

  1. 結(jié)構(gòu)體中嵌入結(jié)構(gòu)體

結(jié)構(gòu)體中嵌入結(jié)構(gòu)體,就要注意嵌入的結(jié)構(gòu)體是值類型的還是指針類型的,例如:

type TT struct{
    TT1
    *TT2
}

那么 TT 的方法集合是什么? *TT 的方法集合是什么?

TT 的方法集合就是按照正常值傳遞的來(lái),等于 TT1 的方法集合 加上 *TT2 的方法集合

*TT 的方法集合按照地址傳遞的來(lái),等于 *TT1的方法集合 加上 *TT2 的方法集合

那么類型別名的方法集合又是如何去查看的,有什么需要注意的地方嗎?

那么還是上述方法集合中的案例,我們分別給結(jié)構(gòu)體 TT 定一個(gè)別名,TTB,給接口類型 ITT 定義一個(gè) ITTB ,此時(shí)來(lái)查看別名的方法集合,與其原有類型的方法集合是否有差距

[圖片上傳失敗...(image-10ea33-1697727234625)]

上述程序運(yùn)行結(jié)果如下:

main.ITT mthond set is :
--- Hello1
--- Hello2
main.ITT mthond set is :
--- Hello1
--- Hello2
main.TT mthond set is :
--- Hello1
main.TT mthond set is :
--- Hello1
*main.TT mthond set is :
--- Hello1
--- Hello2
*main.TT mthond set is :
--- Hello1
--- Hello2

通過(guò)打印結(jié)果,我們可以看到,類型別名的方法集合與原有類型的方法集合是一樣的,無(wú)論是結(jié)構(gòu)體類型還是接口類型

知道 receiver 能夠調(diào)用的方法集合有哪些, 那么在具體使用的時(shí)候,就避免出錯(cuò),避免誤解,對(duì)于后續(xù)的接口組合就會(huì)理解的更加明白和清晰了

總結(jié)

本次主要分享了 GO 語(yǔ)言中方法和函數(shù)的關(guān)系,GO 語(yǔ)言中的方法集合如何查看、甄別和使用

歡迎點(diǎn)贊,關(guān)注,收藏

朋友們,你的支持和鼓勵(lì),是我堅(jiān)持分享,提高質(zhì)量的動(dòng)力

[圖片上傳失敗...(image-324050-1697727234625)]

好了,本次就到這里

技術(shù)是開(kāi)放的,我們的心態(tài),更應(yīng)是開(kāi)放的。擁抱變化,向陽(yáng)而生,努力向前行。

我是阿兵云原生,歡迎點(diǎn)贊關(guān)注收藏,下次見(jiàn)~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,488評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,034評(píng)論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 175,327評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,554評(píng)論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,337評(píng)論 6 404
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 54,883評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評(píng)論 3 439
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,114評(píng)論 0 286
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,625評(píng)論 1 332
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,555評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,737評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評(píng)論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 43,973評(píng)論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,362評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,615評(píng)論 1 280
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,343評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,699評(píng)論 2 370

推薦閱讀更多精彩內(nèi)容

  • 1. 概述 Go 語(yǔ)言中 的方法 ( Method ) 是一種作用 于特定類型變量 的函數(shù) 。這種特定類型變量叫...
    楚江云閱讀 425評(píng)論 0 2
  • 1、Go 中有一個(gè)概念: 1)Go 方法是作用在接收者(receiver)上的一個(gè)函數(shù),接收者是某種類型的變量。因...
    liuxuech閱讀 323評(píng)論 0 0
  • Go語(yǔ)言方法 概念 Go語(yǔ)言中的方法就是一個(gè)特殊的函數(shù), 這個(gè)函數(shù)和某種數(shù)據(jù)綁定在一起,就稱之為方法一般都是和結(jié)構(gòu)...
    超級(jí)皮波9閱讀 1,110評(píng)論 3 0
  • 定義一個(gè)結(jié)構(gòu)體,將函數(shù)和結(jié)構(gòu)體綁定在一起的東西就是方法 格式:func (接收者名稱 接收者類型)函數(shù)名稱(形參列...
    AuglyXu閱讀 4,837評(píng)論 3 7
  • 方法是和數(shù)據(jù)類型綁定的,自定義數(shù)據(jù)類型可以用方法 Go語(yǔ)言工廠模式,如果一個(gè)包內(nèi)結(jié)構(gòu)體名字首字母為小寫(xiě),需要編寫(xiě)n...
    Jaeyok閱讀 277評(píng)論 0 1