Golang学习笔记_14——切片
Golang学习笔记_15——range
Golang学习笔记_16——Map
文章目录
- 方法
- 1. 介绍
- 2. 定义
- 3. 值接收者和指针接收者
- 4. 调用
- 5. 用途
- 6. 方法与函数的区别
- 7. 建议选择指针作为接收者
- 源码
方法
Go 没有类。不过你可以为类型定义方法。
方法就是一类带特殊的 接收者 参数的函数。
方法接收者在它自己的参数列表内,位于 func
关键字和方法名之间。
1. 介绍
在Go语言中,方法(Method)是一种带有接收者(Receiver)的函数。
接收者可以是值接收者(Value Receiver)或指针接收者(Pointer Receiver),并且它允许我们为特定类型定义附加的行为。
方法使得我们可以像面向对象编程一样为结构体(Struct)或其他类型定义方法,但Go本身并不是纯面向对象的语言。
记住:方法只是个带接收者参数的函数。
2. 定义
func (recv ReceiverType) MethodName(parameters) (results) {// 方法体
}
recv
:接收者变量名,它是方法作用的对象实例。ReceiverType
:接收者的类型,可以是值类型或指针类型。MethodName
:方法的名称。parameters
:方法的参数列表。results
:方法的返回值列表。
3. 值接收者和指针接收者
-
值接收者:如果方法使用值接收者,那么在方法内部对接收者所做的修改不会影响原始数据。
type Person struct {Name stringAge int }func (p Person) Greet() {fmt.Println("Hello, my name is", p.Name) }
-
指针接收者:如果方法使用指针接收者,那么在方法内部对接收者所做的修改会影响原始数据。通常,如果方法需要修改接收者的状态,应该使用指针接收者。
func (p *Person) HaveBirthday() {p.Age++ }
4. 调用
调用方法与调用普通函数类似,但方法是通过接收者实例来调用的。
type Person struct {Name stringAge int
}func (p Person) SayHello() {fmt.Printf("%s say: Hello\n\n", p.Name)
}func (p *Person) addAge() {p.Age = p.Age + 1fmt.Printf("%s say: Added age to the new age: %d\n", p.Name, p.Age)
}
测试方法
func TestPerson_SayHello(t *testing.T) {bob := Person{"Bob", 20}bob.SayHello()
}func TestPerson_addAge(t *testing.T) {tom := Person{"Tom", 30}tom.addAge()
}
输出结果
=== RUN TestPerson_addAge
Tom say: Added age to the new age: 31
--- PASS: TestPerson_addAge (0.00s)
PASS
5. 用途
- 封装行为:将特定类型的操作封装在方法内部,使得代码更加模块化。
- 数据抽象:通过方法隐藏数据结构的实现细节,只暴露必要的接口。
- 多态:通过接口(Interface)和方法,可以实现Go语言中的多态特性。
6. 方法与函数的区别
- 方法是带接收者的函数,而普通函数则没有接收者。
- 方法是通过类型实例调用的,而函数则是直接通过包名或变量名调用的。
- 带指针参数的函数必须接受一个指针,接受一个值作为参数的函数必须接受一个指定类型的值
- 接收者为指针的的方法被调用时,接收者既能是值又能是指针
- 带指针的接收者被值直接调用时,Go会将值解释为指针。
- 以值为接收者的方法被调用时,接收者既能为值又能为指针
- 带值的接收者被指针调用时,Go会降指针解释为值
7. 建议选择指针作为接收者
- 方法能够修改其接收者指向的值。
- 这样可以避免在每次调用方法时复制该值。若值的类型为大型结构体时,这样会更加高效。
源码
// method_demo.go 文件
package method_demoimport "fmt"type Person struct {Name stringAge int
}func (p Person) SayHello() {fmt.Printf("%s say: Hello\n\n", p.Name)
}func (p *Person) addAge() {p.Age = p.Age + 1fmt.Printf("%s say: Added age to the new age: %d\n", p.Name, p.Age)
}
// method_demo_test.go 文件
package method_demoimport "testing"func TestPerson_SayHello(t *testing.T) {bob := Person{"Bob", 20}bob.SayHello()
}func TestPerson_addAge(t *testing.T) {tom := Person{"Tom", 30}tom.addAge()
}