最近有一个需求需要检验 Go 语言的接口方式是值接收器(Value Receiver)方法还是指针接收器(Pointer Receiver)方法。貌似 Go 没有直接提供的方式,所以需要手动实现。
Go 语言里面,值类型T
和对应的指针类型*T
有着不同的方法集。T
是所有值接收器方法的集合,而*T
是所有值接收器方法和所有指针接收器方法的集合。
获取类型的两种方法集
如果有以下的类型:
1 2 3 4 |
|
则可以通过如下的反射代码来分别获取T
和*T
类型的方法集:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
以上代码会输出:
1 2 3 4 5 |
|
可以看到,值类型T
只有值接收器方法,而指针类型*T
同时有值接收器方法和指针接收器方法。
所以总结一下:
- 如果一个方法仅出现在指针类型的方法集中,那么它是指针接收器
- 如果一个方法同时出现在指针类型和值类型的方法集中,那么它是值接收器
通过反射判断方法是值接收器还是指针接收器
首先定义两个接口:
1 2 3 4 5 6 7 |
|
结构体还是上面代码的S
结构体。
可以通过编写如下代码在运行时判断接收器的类型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
上面的代码将输出:
1 2 3 |
|