一、方法是什么
方法是作用于某个特定类型的函数,例如作用于某个struct结构体的函数或者说是属于某个结构体的函数
二、方法的定义
既然方法属于某个类型,需要有个类型:
// 定义结构体类型 User
type User struct {
Name string
Age int
}
定义一个打印User信息的方法代码如下:方法与函数的区别在于多了个(u User) ,用于标识该方法作用于User结构体或者说属于User结构体。在go中(u User)被称作接收器。
// 定义User的方法
// (u User) 被称作方法接收器
func (u User) PrintUser() {
println("name:", u.Name)
println("age:", u.Age)
}
个人理解可以把接收器当作函数的一个特殊参数代码如下:同样可以打印User的信息,不同的是接收器只能有一个
// 定义一个函数用来打印User的信息
func PrintUser(u User) {
println("name:", u.Name)
println("age:", u.Age)
}
三、方法的调用
package main
// 定义结构体类型 User
type User struct {
Name string
Age int
}
// 定义User的方法用来打印User的信息
// (u User) 被称作方法接收器
func (u User) PrintUser() {
println("name:", u.Name)
println("age:", u.Age)
}
// 定义一个函数用来打印User的信息
func PrintUser(u User) {
println("name:", u.Name)
println("age:", u.Age)
}
// main函数,程序的入口
func main() {
u := User{"tom", 23}
// 方法的调用
u.PrintUser()
// 函数的调用
PrintUser(u)
}
打印结果:
name: tom
age: 23
name: tom
age: 23
四、指针接收器
既然接收器与函数的参数类似,那么也存在传值与传址的问题
package main
// 定义结构体类型 User
type User struct {
Name string
Age int
}
// 定义为指针接收器
func (u *User) PrintUser() {
println("name:", u.Name)
println("age:", u.Age)
}
// 定义为指针接收器
func (u *User) AddUserAge(addAge int) {
u.Age += addAge
}
// main函数,程序的入口
func main() {
// 当接收器是指针类型时:u可以是指针变量,也可以是非指针变量
u := User{"tom", 23}
// 当接收器是指针类型时:u可以是指针变量,也可以是非指针变量
//u := &User{"tom", 23}
// 打印user信息
u.PrintUser()
// 增加user年龄
u.AddUserAge(3)
// 打印user信息
u.PrintUser()
}
四、方法的集合-接口interface
1、方法是属于特定类型的函数,一个方法可以属于多个类型
package main
type Cat struct {
Nmme string
}
type Dog struct {
Nmme string
}
func (c Cat) myNameIs() {
println(c.Nmme)
}
func (d Dog) myNameIs() {
println(d.Nmme)
}
// main函数,程序的入口
func main() {
c := Cat{"cat"}
d := Dog{"dog"}
d.myNameIs()
c.myNameIs()
}
2、一组方法也可以属于某个类型,一组方法的表达格式就是接口定义
// 定义一组方法,即定义一个接口 interface
// 接口的名字Animal
// 包含两个函数
type Animal interface {
myNameIs()
myFoodIs()
}
3、怎么让一组方法属于某个类型,需要组内的每个方法都属于这个类型才可以
// 定义一个类型 Cat
type Cat struct {
Nmme string
Food string
}
func (d Dog) myNameIs() {
println(d.Nmme)
}
func (c Cat) myFoodIs() {
println(c.Food)
}
如上代码接口Animal的两个函数都属于类型Cat了,即一组方法属于了某个类型,这种情况可以表述为:该类型实现了某个接口。
4、一组方法也可以同时属于多个类型,即多个类型可以同时实现相同的接口
type Dog struct {
Nmme string
Food string
}
func (d Dog) myNameIs() {
println(d.Nmme)
}
func (d Dog) myFoodIs() {
println(d.Food)
}
5、接口方法调用
func main() {
c := Cat{"cat", "fish"}
d := Dog{"dog", "bone"}
d.myNameIs() // 打印dog
d.myFoodIs() // 打印bone
c.myNameIs()// 打印cat
c.myFoodIs()// 打印fish
}
当类型实现的某个接口时,类型就拥有该接口的功能即Cat、Dog 都是 Animal,所以上面的代码也可以写成下面样式
func main() {
var animal1, animal2 Animal
animal1 = Cat{"cat", "fish"}
animal2 = Dog{"dog", "bone"}
animal1.myNameIs()
animal1.myFoodIs()
animal2.myNameIs()
animal2.myFoodIs()
}