go中的方法到底是个啥

 

在 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())
}

猜你喜欢

转载自blog.csdn.net/qq_20867981/article/details/82526967