一. 方法
1.1 概述
带有接受者的函数,我们称为方法。本质上一个方法就是一个特殊类型关联的函数。go语言中就可以给任意自定义类型(包括内置类型,但是不包括指针类型)添加对应的方法
方法的语法:
func(receiver ReceiverType)funcName(parms)(results)
- 方法总是绑定对象实例,并隐式将实例作为第一实参
- 参数receiver可以任意命名,如果在方法中没有使用,也是可以省略的
- 参数ReceiverType的类型可以是T或者是T*。 基类型T不能使接口或者指针
- 不支持重载方法,也就是说不能定义名字相同但是参数不同的方法
- 只要接受者类型不同,就算方法名字一样也是不同的方法,不会出现重复定义函数的错误
1.2 给类型添加方法
1.2.1 给基础类型添加方法
type long int
func (tmp long)Add02(other long) long {
return tmp + other
}
func main() {
var a long = 2
result := a.Add02(3)
fmt.Println(result)
}
1.2.2 给结构体类型添加方法
package main
import "fmt"
type Person struct {
name string
sex byte
age int
}
//带有接收者的函数叫做方法
func (p Person)PrintInfo() {
fmt.Println("p = " , p)
}
//通过一个函数,给成员赋值
func (p *Person)SetInfo(m string,s byte ,a int) {
p.name = m
p.age = a
p.sex = s
}
func main() {
p := Person{"mick" , 'm', 12 }
p.PrintInfo()
var p1 Person
p1.SetInfo("mick1" , 'f' , 13)
p1.PrintInfo()
}
1.3 值语义和引用语义
package main
import "fmt"
type Person struct {
name string
sex byte
age int
}
//修改成员变量的值
//参数就是普通变量,不是指针,值语义 不能修改 会拷贝一份
func (p Person)SetInfoValue(m string,s byte ,a int) {
p.name = m
p.age = a
p.sex = s
fmt.Printf("SetinfoValue == %p \n" , &p)
}
//参数就是指针,引用语义 , 可以修改
func (p *Person)SetInfoPoint(m string,s byte ,a int) {
p.name = m
p.age = a
p.sex = s
fmt.Printf("SetInfoPoint == %p \n" , &p)
}
func main() {
var p1 Person
fmt.Printf("&p1 == %p \n" , &p1) //打印地址
p1.SetInfoValue("mike", 'm' , 17) //打印内容 修改失败
fmt.Println("p1 = ", p1)
/*
&p1 == 0xc420098020
SetinfoValue == 0xc420098040 //地址不一样,说明函数里拷贝的一份,修改的是拷贝的 不是原来的p1,显示也是没有修改成功的
p1 = { 0 0}
*/
p1.SetInfoPoint("ricky", 'f' , 20) //打印内容 修改成功
fmt.Println("p1 = ", p1)
/*
&p1 == 0xc420098020
SetInfoPoint == 0xc42008e020 //地址一样,说明函数里修改的就是原来的P1,结果也显示修改成功了
p1 = {ricky 102 20}
*/
}
1.4 方法集
类型的方法集是指能被该类型的值调用的所有的方法的集合
用实例value和指针point调用方法不受方法集的约束,编译器编译总是查找全部的方法,并且自动转化receier实参
1.5 方法的继承
package main
import "fmt"
type Person struct {
name string
sex byte
age int
}
func (p *Person)PrintInfo(){
fmt.Printf("name = %s , age = %d , sex = %c" , p.name,p.age,p.sex)
}
//Studet继承了Person的成员字段,就继承了成员和方法
type Student struct {
Person
id int
addr string
}
//Student也实现了一个方法和Person的方法同名,这就是方法的重写
func (s *Student)PrintInfo(){
fmt.Printf("name = %s , age = %d , sex = %c , addr = %s" , s.name,s.age,s.sex , s.addr)
}
func main() {
s := Student{Person{"ricky" , 'm' , 18} , 2 , "nj"}
/*
*/
s.PrintInfo()
}