Golang中的方法集問題

問題提要

之前寫代碼的時候遇到了一個問題:自己編寫了一個接口,然后又寫了一個結(jié)構(gòu)體實現(xiàn)這個接口,在通過函數(shù)調(diào)用接口方法時出現(xiàn)了問題。
代碼如下:

type Validator interface  {
  Valid() bool
}

type LoginInput struct {
  Username string
  Password string
}

func (input *LoginInput) Valid() bool {
  // 一些檢驗邏輯
  // 返回校驗結(jié)果
}

func Handle(v Validator) {
  res := v.Valid()
  // 根據(jù)校驗結(jié)果做一些邏輯處理
}

func main() {
  // 對具體過程做了提煉昧辽,最終邏輯一致
  input := LoginInput{Username: "XXX", Password: "YYY"}
  Handle(input)
}

main中調(diào)用Handle()時傳參失敗酵颁,Goland提示消息如下:Cannot use 'input' (type LoginInput) as type ValidatorType does not implement 'Validator' as 'Valid' method has a pointer receiver

解決方法其實很簡單嫉你,就是調(diào)用Handle()不要傳值,要傳指針躏惋。把調(diào)用改成這樣就行:Handle(&input)

但這是為什么呢幽污?回去翻了翻書,發(fā)現(xiàn)是因為方法集簿姨。

什么是方法集

我們先來看看Golang官方對它的描述:

https://golang.google.cn/ref/spec#Method_sets
A type may have a method set associated with it. The method set of an interface type is its interface. The method set of any other type T consists of all methods declared with receiver type T. The method set of the corresponding pointer type *T is the set of all methods declared with receiver *T or T (that is, it also contains the method set of T). Further rules apply to structs containing embedded fields, as described in the section on struct types. Any other type has an empty method set. In a method set, each method must have a unique non-blank method name.
The method set of a type determines the interfaces that the type implements and the methods that can be called using a receiver of that type.
一個類型會有一個與它關(guān)聯(lián)的方法集距误。interface類型的方法集就是接口本身。其他任意類型T的方法集由接收者為T類型的全部方法構(gòu)成。對應(yīng)的指針類型*T的方法集是由接收者為T*T的全部方法構(gòu)成的(也就是說准潭,它也包含了T的方法集)攘乒。更多的規(guī)則應(yīng)用在包含嵌入字段的結(jié)構(gòu)體上,就像struct types章節(jié)中描述的一樣惋鹅。任何其他類型都有一個空的方法集则酝。在方法集中,每個方法必須具有唯一的非空方法名闰集。
類型的方法集確定類型實現(xiàn)的接口以及可以使用該類型的接收器調(diào)用的方法沽讹。

總結(jié)一下官方文檔表述的意思,我們得到如下一張表:

變量類型 方法接收器類型
T (t T)
*T (t T) + (t *T)

對于T類型武鲁,它的方法集只包含接收者類型是T的方法爽雄;而對于*T類型,它的方法集則包含接收者為T*T類型的方法沐鼠,也就是全部方法挚瘟。
只有一個類型的方法集完全涵蓋了接口的方法集后,這個類型才會被認為是接口的實現(xiàn)類型饲梭。
從這里可以看出來乘盖,我們最開始的代碼就是因為LoginInput類型的方法集中沒有notify方法,所以函數(shù)調(diào)用失敗了憔涉。

結(jié)構(gòu)體的方法調(diào)用與方法集之間的關(guān)系

其實到這里就會有個疑問:平時調(diào)用方法時订框,無論變量類型是值類型還是指針類型都能調(diào)用成功,也沒出過問題啊兜叨。
這里其實是Golang的一個語法糖:在使用選擇器(Selectors)調(diào)用方法時穿扳,編譯器會幫你做好取址或取值的操作的。
下面通過代碼說明一下這個關(guān)系:

type StructA struct {}

func (s StructA) ValueReceiver () {}

func (s *StructA) PointReceiver () {}

func main() {
  value := StructA{}
  point := &value
  // 編譯器不做處理国旷,就是value.ValueReceiver()
  value.ValueReceiver()
  // 其實是(&value).ValueReceiver()的簡便寫法
  value.PointReceiver()
  // 其實是(*point).ValueReceiver()的簡便寫法
  point.ValueReceiver()
  // 編譯器不做處理矛物,就是point.ValueReceiver()
  point.PointReceiver()
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市跪但,隨后出現(xiàn)的幾起案子履羞,更是在濱河造成了極大的恐慌,老刑警劉巖特漩,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吧雹,死亡現(xiàn)場離奇詭異骨杂,居然都是意外死亡涂身,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門搓蚪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蛤售,“玉大人,你說我怎么就攤上這事°材埽” “怎么了揣钦?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長漠酿。 經(jīng)常有香客問我冯凹,道長,這世上最難降的妖魔是什么炒嘲? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任宇姚,我火速辦了婚禮挤土,結(jié)果婚禮上空盼,老公的妹妹穿的比我還像新娘。我一直安慰自己琐馆,他們只是感情好夭拌,可當我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布魔熏。 她就那樣靜靜地躺著,像睡著了一般鸽扁。 火紅的嫁衣襯著肌膚如雪蒜绽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天桶现,我揣著相機與錄音滓窍,去河邊找鬼。 笑死巩那,一個胖子當著我的面吹牛吏夯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播即横,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼噪生,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了东囚?” 一聲冷哼從身側(cè)響起跺嗽,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎页藻,沒想到半個月后桨嫁,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡份帐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年璃吧,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片废境。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡畜挨,死狀恐怖筒繁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情巴元,我是刑警寧澤毡咏,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站逮刨,受9級特大地震影響呕缭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜修己,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一臊旭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧箩退,春花似錦离熏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至啥刻,卻和暖如春奸鸯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背可帽。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工娄涩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人映跟。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓蓄拣,卻偏偏與公主長得像,于是被迫代替她去往敵國和親努隙。 傳聞我的和親對象是個殘疾皇子球恤,可洞房花燭夜當晚...
    茶點故事閱讀 45,512評論 2 359

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