方法method
-
Go中虽没有class,但依旧有method(结构在承担class这个任务)
-
通过显示说明receiver来实现与某个类型的组合
-
只能为同一个包中的类型定义方法
-
Receiver可以是类型的值或者指针
-
不存在方法重载
-
可以使用值或者指针来调用方法,编译器会自动完成转换
-
从某种意义上来说,方法是函数的语法糖,因为receiver其实就是方法所接收的第1个参数(Method Value vs.Method Expression)
-
如果外部结构和嵌入结构存在同名方法,则优先调用外部结构的方法
-
类型别名不会拥有底层类型所附带的方法
-
方法可以调用结构中的非公开字段
方法的声明和使用
type A struct {
Name string
}
type B struct {
Name string
}
func main() {
a := A{} //声明结构A
a.Print() //调用这个方法 Go会自动的通过识别转换判断以值调用这个方法或者这个字段
fmt.Pr intln(a.Name)
b := B{}
b.Print()
fmt.Println(b.Name)
}
//方法和method是绑定在一起的
//func (参数 receiver接收者类型) 方法的名称(参数列表){}
//receiver是函数的第一个接受者,并且是强制规定的
func (a *A) Print() { //指针传递
a.Name = "AA"
fmt.Println("A")
}
func (b B) Print() { //以值传递,只是得到一个拷贝
b.Name = "BB"
fmt.Println("B")
}
运行结果:
方法的绑定
通过方法的绑定可以为任何一种type进行方法的结合
//底层类型是int,可以为它添加一个Print方法,是Go的一个灵活之处,通过方法的形式进行非常自由的结构的绑定
//在类型别名中 "TZ" 和 int 之间的转换是强制的。进行强制类型的转换是因为所附带的方法是不一定的
//通过方法的绑定可以为任何一中type定义的类型进行方法的结合
//int 类型是一个内置类型,无法进行绑定。方法的绑定只能对相同包起到作用
type TZ int
func main() {
var a TZ //定义一个结构
a.Print()
}
func (a *TZ) Print() {
fmt.Println("TZ")
}
运行结果:
对比
Method Value 和Method Expression的对比
方法和函数之间有一种互通
type TZ int
func main() {
var a TZ //定义一个结构
a.Print() //Method Value: 已经声明了receiver(a *TZ),然后通过这种类一样的调用方法
(*TZ).Print(&a) //Method Expression
}
func (a *TZ) Print() {
fmt.Println("TZ")
}
运行结果:
权限的问题
方法可以访问结构的私有字段,方法的访问权限很高
type A struct {
name string
}
//这里小写的私有实在package包中是公有的,不能被外部的包访问到
func main() {
a := A{}
a.Print()
fmt.Println("------")
fmt.Println(a.name)
}
func (a *A) Print() {
a.name = "123"
fmt.Println(a.name)
}
运行结果:
尝试声明一个底层类型为int的类型,并实现调用某个方法就递增100
如: a:=0,调用a.Ircrease()之后,a从0变成100
package main
import (
"fmt"
)
type TZ int
func (tz *TZ) Increase(num int) {
*tz += TZ(num)
}
func main() {
var a TZ
a.Increase(100)
fmt.Println(a)
}
运行结果: