1. 方法定义
Golang 方法总是绑定对象实例,并隐式将实例作为第一实参 (receiver)。
一个方法就是一个包含了接受者的函数,接受者可以是命名类型或者结构体类型的一个值或者是一个指针。
所有给定类型的方法属于该类型的方法集。
参数和返回值可以省略
package main
type Test struct{}
// 无参数、无返回值
func (t Test) method0() {
}
// 单参数、无返回值
func (t Test) method1(i int) {
}
// 多参数、无返回值
func (t Test) method2(x, y int) {
}
// 无参数、单返回值
func (t Test) method3() (i int) {
return
}
// 多参数、多返回值
func (t Test) method4(x, y int) (z int, err error) {
return
}
// 无参数、无返回值
func (t *Test) method5() {
}
// 单参数、无返回值
func (t *Test) method6(i int) {
}
// 多参数、无返回值
func (t *Test) method7(x, y int) {
}
// 无参数、单返回值
func (t *Test) method8() (i int) {
return
}
// 多参数、多返回值
func (t *Test) method9(x, y int) (z int, err error) {
return
}
func main() {}
下面定义一个结构体类型和该类型的一个方法:
golang : golang@golang.com
go : go@go.com
解释: 首先我们定义了一个叫做 User 的结构体类型,然后定义了一个该类型的方法叫做 Notify,该方法的接受者是一个 User 类型的值。要调用 Notify 方法我们需要一个 User 类型的值或者指针。
在这个例子中当我们使用指针时,Go 调整和解引用指针使得调用可以被执行。注意,当接受者不是一个指针时,该方法操作对应接受者的值的副本(意思就是即使你使用了指针调用函数,但是函数的接受者是值类型,所以函数内部操作还是对副本的操作,而不是指针操作。
我们修改 Notify 方法,让它的接受者使用指针类型:
package main
import (
"fmt"
)
//结构体
type User struct {
Name string
Email string
}
//方法
func (u *User) Notify() {
fmt.Printf("%v : %v \n", u.Name, u.Email)
}
func main() {
// 值类型调用方法
u1 := User{"golang", "golang@golang.com"}
u1.Notify()
// 指针类型调用方法
u3.Notify()
}
输出结果:
方法不过是一种特殊的函数,只需将其还原,就知道 receiver T 和 *T
的差别。
package main
import "fmt"
type Data struct {
x int
}
func (self Data) ValueTest() { // func ValueTest(self Data);
fmt.Printf("Value: %p\n", &self)
}
func (self *Data) PointerTest() { // func PointerTest(self *Data);
fmt.Printf("Pointer: %p\n", self)
}
func main() {
d := Data{}
p := &d
fmt.Printf("Data: %p\n", p)
d.ValueTest() // ValueTest(d)
d.PointerTest() // PointerTest(&d)
p.ValueTest() // ValueTest(*p)
p.PointerTest() // PointerTest(p)
}
输出:
Data: 0xc42007c008
Value: 0xc42007c018
Pointer: 0xc42007c008
Value: 0xc42007c020
Pointer: 0xc42007c008
1.1.2. 普通函数与方法的区别
1.对于普通函数,接收者为值类型时,不能将指针类型的数据直接传递,反之亦然。
2.对于方法(如struct的方法),接收者为值类型时,可以直接用指针类型的变量调用方法,反过来同样也可以。
valueIntTest: 12
pointerIntTest: 15
hello world
hello world
hello golang