前面介紹了很多心法及基礎觀念,接下來我要來繼續介紹身為gopher你應該理解的方法本質
Go語言沒有面向物件的元素,像是類別,繼承...,但並不代表他不能使用相似的觀念,不過也代表可能需要換個方式去習慣這一套Go獨有的思考模式
在 Go 中,可以使用「結構體」(structs)來模擬類,而方法(methods)是關聯到結構體的函數。這些方法使用一個特殊的參數稱為「接收器」(receiver)
先來看基本語法
func (receiver T) MethodName(參數列表) (返回值列表) {
// ...
}
在 Go 語言中,方法是與某一類型相關聯的函數。這個特定類型被稱為接收器。當一個方法被定義在接收器上,這意味著該方法已綁定到該類型,可以通過這個類型的值或者指針來調用該方法
所以你可以這樣做
var t T
t.MethodName(參數列表)
舉個例子
type Rectangle struct {
Length, Width float64
}
// Area 方法綁定到 Rectangle 類型
func (r Rectangle) Area() float64 {
return r.Length * r.Width
}
func main() {
rect := Rectangle{Length: 5, Width: 4}
fmt.Println(rect.Area()) // 輸出:20
}
go 方法具有以下特點
方法名的首字母大寫表示這個方法是公開的,也就是說它可以被其他的包訪問,如果首字母是小寫,則這個方法是私有的,只能被其所在的包訪問
方法定義和類型定義要在同一個package內
type MyInt int
func (m MyInt) IsEven() bool {
return m%2 == 0
}
每個方法只有一個receiver參數,不支持多receiver參數列表,一個方法只能綁定一個基本型
Go沒有類,所以要透過receiver組在一起
type T struct {
a int
}
func (t T) Get() int {
return t.a
}
func (t *T) Set(a int) int {
t.a = a
return t.a
}
在 Go 裡,接收器就像是方法所屬的那個物件,他允許該方法訪問和修改物件的數據,意思也是接受器也是參數的一部分
所以我們也可以把上述程式碼等價成
func Get(t T) int{
return t.a
}
func Set(t *T, a int) int{
t.a = a
return t.a
}
我們可以說,go方法的本質:當我們說一個方法綁定到一個類型時,其實質上就是這個方法將該類型的一個實例(或指向該實例的指針)作為其第一個參數
你該是要使用值接受器還是指標接受器呢?選擇使用值接收器還是指針接收器主要取決於方法的目的、結構的大小以及你想要達到的語義效果
方法的 receiver 可以是值類型或指針類型,這決定了方法是如何與它所綁定的類型的實例互動的
type MyType struct {
// ... fields ...
}
func (m MyType) MyMethod() {
// ... method body ...
}
type MyType struct {
// ... fields ...
}
func (m *MyType) MyPointerMethod() {
// ... method body ...
}
根據你的需求(例如,是否需要在方法中修改 receiver 的狀態),你可以選擇使用值類型的 receiver 還是指針類型的 receiver