惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Jina AI
Jina AI
大猫的无限游戏
大猫的无限游戏
T
Tailwind CSS Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
WordPress大学
WordPress大学
Last Week in AI
Last Week in AI
Hugging Face - Blog
Hugging Face - Blog
阮一峰的网络日志
阮一峰的网络日志
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
人人都是产品经理
人人都是产品经理
V
V2EX
博客园 - 叶小钗
雷峰网
雷峰网
小众软件
小众软件
量子位
V
Visual Studio Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
The GitHub Blog
The GitHub Blog
Martin Fowler
Martin Fowler
G
Google Developers Blog
博客园_首页
博客园 - Franky
有赞技术团队
有赞技术团队
宝玉的分享
宝玉的分享

博客园 - ayanmw

zhile的落幕: 我居然才知道2024年zhile就关停网站了,热心大佬暂时隐退 极度推荐: 9router 一个npm服务,可以让你将白嫖到的所有AI token以及付费API都集中到一起 开源项目介绍 OpenTeam 命令行 检测验证网站的 SSL证书 是否安全 Nginx 使用自签名 SSL 证书 关闭夸克浏览器在windows资源管理器中,图片右键菜单的万能转换开关 golang的defer 深坑 Windows Terminal 清屏方法 Ctrl+Shift+K 免费二级域名以及设置SSL证书和解析 docker加速镜像 golang + AI 写一个可以 一键让nas下载百度网盘链接的文件 的程序 raid 为什么而不可以两个硬盘交叉读写和交叉备份? google-protobuf库 在golang语言下的插件扩展 golang 空切片和nil切片 有区别吗? golang json库 忽略 omitempty golang 获得一个结构体的字节大小 吐槽 WPS 流氓行为: WPS 未经用户允许, 就建立了 WPS本地云盘 , 然后 云文档的文件 莫名其妙的的被删除了, 现在只能开会员恢复WPS云空间回收站的文件. 预测未来会有 内嵌AI大模型的游戏 好奇: windows10+都可以运行多个linux子系统了,为什么不支持运行多个windows子系统呢? gorm使用事务并发情况下切有最大mysql连接数限制的情况下的BUG,踩坑了 2024年 个人养老金 账户 应知应会 两个Mysql唯一索引的交换: 避免重复索引 Duplicate entry '3' for key 'priority_UNIQUE'
Go语言: golang如何判断一个结构体的一个方法是匿名组合的,还...
ayanmw · 2024-06-13 · via 博客园 - 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 目前,获得的 方法的第一个输入参数,永远是 最外层的那个,而不是 代码里面的那个结构。真是忧伤的结果。
所以目前还是无法获得 该方法 是不是 匿名结构体 里面的方法的。