页首Html代码

返回顶部

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 目前,获得的 方法的第一个输入参数,永远是 最外层的那个,而不是 代码里面的那个结构。真是忧伤的结果。
所以目前还是无法获得 该方法 是不是 匿名结构体 里面的方法的。

posted @ 2024-06-13 10:58  ayanmw  阅读(40)  评论(0编辑  收藏  举报

页脚Html代码