go中的方法到底是個啥
阿新 • • 發佈:2018-12-30
在 Go 語言裡,方法和函式只差了一個,那就是方法在 func 和識別符號之間多了一個引數。
type user struct {
name string,
email string,
}
//這是函式的定義
func notify(email string) {
fmt.Println("Email is %s", email)
}
//這是方法的定義
func (u user) notify(email string) {
fmt.Println("Email is %d", email)
}
我們可以看到,方法是在 func 和 notify 之間多了一個 user 型別的引數 u,這個 u 就稱作接收者。
首先,我們是先要定義一個型別,比如就是 user 好了,然後我們再定義方法。
type user struct {
name string
email string
}
func (u user) notify() {
fmt.Println("Email is %d", u.email)
}
func (u *user) changeEmail(email string) {
u.email = email
}
我們定義了兩個方法,一個是 notify,它是值接收者方法;還有一個是 changeEmail,它是指標接收者方法。可以看到,值接收者方法,接收者是一個副本,無法修改;指標接收者是引用,可以修改。
值接收者方法:
package main
import (
"fmt"
)
type Vertex struct {
X, Y float64
}
func (v Vertex)Abs() {
v.Y=66
v.X=66666
}
func main() {
v := Vertex{3, 4}
fmt.Println(v)
v.Abs()
fmt.Println(v)
}
輸出:
{3 4}
{3 4}
指標接收者方法:
package main import ( "fmt" ) type Vertex struct { X, Y float64 } func (v *Vertex)Abs() { v.Y=66 v.X=66666 } func main() { v := Vertex{3, 4} fmt.Println(v) v.Abs() fmt.Println(v) }
輸出:
{3 4}
{66666 66}
我們再來看一下呼叫。
daryl := {"daryl", "[email protected]"}
daryl.changeEmail("[email protected]")
daryl.notify()
看看,是不是很熟悉! daryl 就是物件,name 和 email 就是屬性,notify 和 changeEmail 就是它的方法。只是,不同的是,我們沒有將它放到 class 中,而是用另外一種方式讓它們結合了,有了關係!
方法宣告時要注意以下幾點:
1.接收者的型別定義和方法宣告必須在同一包內
檢視專案結構:
我們在包1內的hello.go內建立了個struct結構,在method1.go內建立了M1方法,在包2下面的method2.go檔案內也建立了M1方法,其中method1.go的M1方法建立成功,method2.go的M1方法建立失敗。
2.不能為內建型別宣告方法
//這樣是可以的
type MyFloat float64
func (f MyFloat) Abs() float64 {
if f < 0 {
return float64(-f)
}
return float64(f)
}
func main() {
f := MyFloat(-math.Sqrt2)
fmt.Println(f.Abs())
}
//不能為內建型別建立方法
func (f float64) Abs() float64 {
if f < 0 {
return float64(-f)
}
return float64(f)
}
func main() {
f := float64(-math.Sqrt2)
fmt.Println(f.Abs())
}