Go语言: golang如何判断一个结构体的一个方法是匿名组合的,还是该结构体自己的方法?
起因
由于我所在项目 使用了 根据反射获取 Method 来注册RPC消息,但是我开发了一个模块,里面匿名组合了1个基础的结构,为了方便调用里面的方法,而不用每次都加一个中健变量 mgr.user.XXXX
.
但是突然发现,所有的方法都执行了两遍,经过同事排查,终于发现是我匿名组合的问题了.
解决问题
既然发现问题,为了避免再次出现类似的问题,应该从底层判断,如果这个方法是匿名的,就不进行注册,至少要打印日志.
但是我发现代码好像没办法直接判断一个方法是否是匿名组合的:
for i := 0; i < t.NumMethod(); i++ {
methodType := t.Method(i)
if methodType.Anonymous ??????????
}
这个methodType 刚好是一个结构体,查看是:
// Method represents a single method.
type Method struct {
// Name is the method name.
Name string
// PkgPath is the package path that qualifies a lower case (unexported)
// method name. It is empty for upper case (exported) method names.
// The combination of PkgPath and Name uniquely identifies a method
// in a method set.
// See https://golang.org/ref/spec#Uniqueness_of_identifiers
PkgPath string
Type Type // method type
Func Value // func with receiver as first argument
Index int // index for Type.Method
}
// IsExported reports whether the method is exported.
func (m Method) IsExported() bool {
return m.PkgPath == ""
}
没办法直接判断是否是匿名的.
难道 就没办法了么?
不甘心,就问了一下kimi
标题部分:如何判断一个结构体的方法是匿名组合还是结构体自己的方法?
- 使用reflect.TypeOf()获取结构体的类型。
- 使用MethodByName()方法获取结构体的方法。
- 检查方法的NumIn()参数,如果包含接收器(receiver),则可以进一步检查接收器的类型。
- 如果接收器的类型与结构体的类型相同,则该方法是结构体自己的方法;如果接收器的类型是结构体内部的匿名字段的类型,则该方法是匿名组合字段的方法。
package main
import (
"fmt"
"reflect"
)
type Outer struct {
Inner
}
type Inner struct {
Value int
}
func (i *Inner) SetValue(val int) {
i.Value = val
}
func (o *Outer) OuterMethod() {
fmt.Println("Outer method called")
}
func main() {
var outer Outer
// 反射获取Outer类型的方法集
methods := reflect.TypeOf(outer).Method //此处有点bug,不过不是核心问题,下面代码是核心.
for _, method := range methods {
// 获取方法的接收器类型
recvType := method.Type.In(0)
// 检查接收器类型是否与Outer相同 if recvType == reflect.TypeOf(outer) { fmt.Printf("Method %s is an Outer method\n", method.Name) } else { fmt.Printf("Method %s is an Inner method\n", method.Name) }
}
}
一个结构体的方法,它的第一个输入参数一定是结构体自己,根据这个隐藏条件,来判断 就可以知道 该方法是否是本结构体的匿名组合的方法了.
Kimit chat 威武,月之暗面 威武!!!!!!!
点击链接查看和 Kimi 智能助手的对话 https://kimi.moonshot.cn/share/cpl60bqtnn0vd4e12r10
不好意思,AI在一本正经的胡说八道。
经过测试,发现,golang1.22 目前,获得的 方法的第一个输入参数,永远是 最外层的那个,而不是 代码里面的那个结构。真是忧伤的结果。
所以目前还是无法获得 该方法 是不是 匿名结构体 里面的方法的。
------------------------------------------------------------------------------------------------
一定要专业!本博客定位于 ,C语言,C++语言,Java语言,Android开发和少量的Web开发,之前是做Web开发的,其实就是ASP维护,发现EasyASP这个好框架,对前端后端数据库 都很感觉亲切啊。. linux,总之后台开发多一点。以后也愿意学习 cocos2d-x 游戏客户端的开发。