這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。 Go不像其它面相對象語言一樣可以寫個class,然後在class裡面寫一堆方法,但是它也很巧妙的實現了這種效果,我們只需要在普通函數前面加個接受者(receiver,寫在函數名前面的括弧裡面),這樣編譯器就知道這個函數(方法)屬於哪個struct了。
下面是簡單樣本:
type A struct {
Name string
}
func (a A)foo() { //接收者寫在函數名前面的括弧裡面
fmt.Println("foo")
}
func main() {
a := A{}
a.foo() //foo
}
需要注意的是,因為Go不支援函數重載,所以某個接收者(receiver)的某個方法只能對應一個函數,比如下面的就屬於方法重複,編譯無法通過:
func (a A)foo() {
fmt.Println("foo")
}
func (a A)foo(i int) {
fmt.Println(i)
}
這些可以叫做是方法綁定,接收者不僅可以是struct類型,還可以是任意自訂的其它類型,舉個栗子:
type Integer int
func (integer *Integer)talk() {
fmt.Println("i am ",*integer)
}
func main() {
var i Integer = 250
i.talk() //i am 250
}
這下知道方法綁定是多麼的靈活了吧
注意方法綁定只能綁定當前包裡的類型
其實有兩種調用方式,上面講的那種官方管它叫method value,還有另一種調用方式,叫method expression:
type Integer int
func (integer *Integer)talk() {
fmt.Println("i am ",*integer)
}
func main() {
var i Integer = 250
(*Integer).talk(&i) //i am 250
}
最後說下存取權限,因為Go是以大小寫來區分是公有還是私人,但都是針對包層級的,所以在包內所有的都能訪問,而方法綁定本身只能綁定包內的類型,所以方法可以訪問接收者所有成員。如果是包外調用某類型的方法,則需要看方法名是大寫還是小寫,大寫能被包外訪問,小寫只能被包內訪問。