在GO语言中,方法是与某个类型绑定的函数,可以操作这个类型的数据。
与函数的区别在于在定义方法的时候需要有一个接收者,用于指定它属于哪个类型
//函数定义
func sum(){
……
}
//方法定义
func (name type)sum(){
……
}
接收者类型可以是结构体类型,或者非结构体的自定义别名类型
我们先来看非结构体自定义别名类型,什么是自定义别名类型?就是给int这样的类型取一个新的名字
type myint int
func main(){
var x myint = 10//本质上还是int只不过换了个类型的名字
}
这就是自定义别名类型。
我们在拥有一个自定义别名类型之后就可以去实现方法了
type myint int
func main() {
var num myint
num = 10086
num.printinfo()
}
func (x myint) printinfo() {
println(x)
}
//这就是一个简单的,自定义别名类型的方法
在类型体内可以对x进行各种运算,方法也可以有返回值,参数列表
type myint int
func main() {
var num myint
num = 10086
key := num.printinfo(123)
println(key)
}
func (x myint) printinfo(num int) int {
if int(x) != num {//这边的类型记得处理一下,不然没法比较
return 1
} else {
return 0
}
}
那我如果想在方法里面修改了接收者的值之后,对这个只值进行修改然后映射到原来的上面应该怎么办?这时候就需要指针的help了捏
func main() {
var num *myint
var x myint = 10086
num = &x //num是一个地址,指向x。并且他俩类型相同
num.printinfo()
println(*num)//输出444,证明值被改变
}
func (x *myint) printinfo() {
*x = 444 //x是一个地址,需要解地址符
fmt.Printf("%v", x)
}
但是这些都不是很重要,方法这部分的重点在于和结构体的结合
下面我们来看看方法的接收者作为结构体吧
type worker struct {//定义结构体
age int
name string
}
func main() {
student := worker{name: "王二狗", age: 18}//创建结构体对象,并赋初值
println(student.name, "今年", student.age, "岁了")
student.gongzuo()//调用方法
println(student.name, "今年", student.age, "岁了")//值未改变
}
func (people worker) gongzuo() {
people.age++
fmt.Println("给", people.name, "改名字")
people.name = "Jack"
println(people.name, "正在工作")
}
输出结果:
王二狗 今年 18 岁了
给 王二狗 改名字
Jack 正在工作
王二狗 今年 18 岁了
我们会发现,虽然我们能访问这个结构体内的字段,但是没有办法改变它的值!
这时候又双叒叕需要指针了,我们这时候需要把接收者类型改为结构体指针类型
type worker struct {
age int
name string
}
func main() {
student := worker{name: "王二狗", age: 18}
println(student.name, "今年", student.age, "岁了")
student.gongzuo()
println(student.name, "今年", student.age, "岁了")
}
func (people *worker) gongzuo() {
people.age++
fmt.Println("给", people.name, "改名字")
people.name = "Jack"
println(people.name, "正在工作")
}
最后结果:
王二狗 今年 18 岁了
给 王二狗 改名字
Jack 正在工作
Jack 今年 19 岁了
乍一看两段代码似乎一模一样,但是乍一看只是乍一看,经不起细看。我们只添加了一个*就改变了这个代码的运行结果。这个*加在了方法接收者类型那里func (people *worker) gongzuo() {
这就说明我们接收者类型是指针类型,从结构体的值传递进化到了结构体指针的引用传递!!!
同样的,子类“继承”父类之后也可以使用父类的方法
type worker struct {
age int
name string
}
type people struct {
worker
name string
}
func main() {
//继承中的方法
sta := people{
worker: worker{18, "tiantain"},
name: "ohho",
}
sta.use()//调用父类的方法
}
func (alpha *worker) use() {
println("nihao,alpha被调用")
}
方法重写,依据上面的代码,sta.use()调用的是父类的方法,我们为子类设计一个方法(这个方法的名字和父类相同,只不过接收者改为了子类)。然后通过sta.use()调用这个方法的时候,会调用我们新添加的那个类
func (alpha *people)use(){
println("我是子类")
}