定義一個接口 if
type?if?interface{? ??
????Method1() string
}
定義一個結(jié)構(gòu)體 st
type?st?struct{? ?
????msg string
}
定義一個測試方法test, 可以接收 實現(xiàn)了if接口的實例 做為形參
func test (i if){? ?
????i.Method1()
}
測試1:?結(jié)構(gòu)體通過 值接收者 實現(xiàn) Method1
func (s st) Method1() string{? ?
????return s.msg
}
func main(){? ?
????s1 := st{"test"}? ?
????s2 := &st{"test"}? ?
????test(s1)? ?
????test(s2)
}
測試可以通過,沒有異常
測試2: 結(jié)構(gòu)體通過 指針接收者 實現(xiàn) Method1:
func (s *st) Method1() string{????
????return s.msg
}
func main(){? ?
????s1 := st{"test"}? ?
????s2 := &st{"test"} ??
????test(s2) //正常執(zhí)行
? ? test(s1) ?//拋出錯誤?(st doesn't implement interface (Method1 has pointer receiver) ??
}
關(guān)于 編譯起拋出的錯誤"st doesn't implement interface (Method1 has pointer receiver)"
要了解用指針接收者來實現(xiàn)接口時為什么結(jié)構(gòu)體類型 的值無法實現(xiàn)該接口,需要先了解方法集,方法集定義了一組關(guān)聯(lián)到給定類型的值或者指針的方法.定義方法時使用的接收者類型決定了這個方法是關(guān)聯(lián)到值還是關(guān)聯(lián)到指針,還可以是兩個都關(guān)聯(lián).
簡單的可以認為,go編譯器定義了一個規(guī)則,如果使用指針接收者來實現(xiàn)一個接口,那么只有指向那個類型的指針才能夠?qū)崿F(xiàn)對應(yīng)的接口。如果使用值接收者來實現(xiàn)一個接口,那么這個類型的值和指針都能夠?qū)崿F(xiàn)對應(yīng)的接口。
想一想也可以這么理解,方法實參都是值傳遞,使用指針接收者是為了修改原來結(jié)構(gòu)體的內(nèi)容,你傳給了方法一個值,方法執(zhí)行期間對你這個原始值做了一份值copy, 而你又是想要改變原始值的內(nèi)容,如何能定位到原來的值的地址呢?索性直接編譯報錯,防止這種行為的出現(xiàn)。