Go - Method
OOP
- Go 并不支持
OOP的语法元素(类、对象、继承等),但仍支持方法(Method) - Go 引入 Method 并非为了实现 OOP 编程范式,而是出自 Go 的
组合设计哲学下类型系统实现层面的需要
Method本质上是一个以receiver参数作为第 1 个参数的Function(Go编译器协助转换)
形式
receiver参数是Method和Type之间的纽带
ListenAndServeTLS归属于*Server类型,而非Server类型
receiver
Method必须归属于某个Type,即receiver参数的类型
1 | func (receiver *T或T) MethodName(参数列表) (返回值列表) { |
- 无论 receiver 参数的类型是
*T还是T,receiver 参数的基类型都为T- 如果 receiver 的类型为
T,则这个Method是类型T的一个方法 - 如果 receiver 的类型为
*T,则这个Method是类型*T的一个方法
- 如果 receiver 的类型为
- 每个 Method 只能有
一个receiver 参数,Go 不支持多个receiver 参数或者变长receiver 参数
作用域
receiver、参数、返回值的作用域:函数or方法对应的显式代码块
receiver 部分的参数名不能与方法参数列表中的
形参名,以及具名返回值中的变量名存在冲突
1 | type T struct { |
如果在方法体中,没有用到 receiver 参数,可以
省略receiver 的参数名 -不常用
1 | type T struct { |
receiver 参数的
基类型本身不能为指针类型或者接口类型
1 | type MyInt *int |
1 | type Reader interface { |
Method 声明要与receiver参数的基类型声明放在同一个包内
- 不能为
原生类型添加 Method - 不能跨越 Go 包为其他包的类型声明新方法
1 | func (i int) Foo() string { // cannot define new methods on non-local type int |
1 | import "net/http" |
使用
receiver 参数的
基类型为 T,即 receiver 参数绑定到 T 上,可以通过*T或者T的变量实例调用该方法
1 | type T struct { |
本质
1 | type T struct { |
将 receiver 参数以
第 1 个参数的身份并入方法的参数列表中,可以等价转换为普通函数
1 | func Get(t T) int { |
方法类型为经过等价转换后的普通函数的函数类型,但这种等价转换是由编译器在编译和生成代码时自动完成的
方法表达式 -
Method Expression- 类似于 Java 的反射
1 | func main() { |
本质:以
receiver参数作为第 1 个参数的普通函数
1 | func main() { |
实践
1 | type field struct { |
等价转换
1 | func main() { |
修改:将
receiver类型从*field改为field
1 | type field struct { |
由于
循环变量是复用的,要警惕出现&{循环变量}的场景
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.












