Go语言: golang如何判断一个结构体的一个方法是匿名组合的,还是该结构体自己的方法?
你看到的这个文章来自于http://www.cnblogs.com/ayanmw
起因
由于我所在项目 使用了 根据反射获取 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 目前,获得的 方法的第一个输入参数,永远是 最外层的那个,而不是 代码里面的那个结构。真是忧伤的结果。
所以目前还是无法获得 该方法 是不是 匿名结构体 里面的方法的。
转载请注明出处:http://www.cnblogs.com/ayanmw 我会很高兴的!
------------------------------------------------------------------------------------------------
一定要专业!本博客定位于 ,C语言,C++语言,Java语言,Android开发和少量的Web开发,之前是做Web开发的,其实就是ASP维护,发现EasyASP这个好框架,对前端后端数据库 都很感觉亲切啊。. linux,总之后台开发多一点。以后也愿意学习 cocos2d-x 游戏客户端的开发。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!