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.