Golang 反射问题,从接口反射方法

2023-10-16 11:49:35 +08:00
 Qjues
package main

import (
	"fmt"
	"reflect"
)

type Interface interface {
	Interface(arg int) string
}

type Struct struct {
}

func (s Struct) Interface(arg int) string {
	//TODO implement me
	panic("implement me")
}

func main() {
	of := reflect.TypeOf(Struct{})
	m1, _ := of.MethodByName("Interface")
	fmt.Println(m1.Type.NumIn()) // output 2 -> in[0] is Struct
	fmt.Println(m1.Type.In(0))

	m2, _ := reflect.TypeOf((*Interface)(nil)).Elem().MethodByName("Interface")
	fmt.Println(m2.Type.NumIn()) // output 1 -> in[0] is int
	fmt.Println(m2.Type.In(0))

	m3 := reflect.ValueOf(Interface.Interface)
	fmt.Println(m3.Type().NumIn()) // output 2 -> in[0] is Interface
	fmt.Println(m3.Type().In(0))
}

想实现接口方法的分析,每个方法的入参第一个应该是接口本身。

通过第一种方案反射出来的方法,入参有 2 个,但是第一个参数是结构体,和接口无关了

通过第二种方案反射出来的方法,入参只有 1 个,缺少接口本身

通过第三种方案反射出来的方法,结果符合预期,但是需要每个方法都硬编码。

1275 次点击
所在节点    Go 编程语言
9 条回复
Qjues
2023-10-16 11:52:25 +08:00
有没有什么其他的方案呢,通过接口可以分析出每个方法的完整类型。
mightybruce
2023-10-16 15:01:53 +08:00
建议直接去看 uber 用反射写的 AOP 控制反转是如何实现。
https://github.com/uber-go/dig
https://github.com/uber-go/fx
mcfog
2023-10-16 19:20:09 +08:00
m1,m2: https://pkg.go.dev/reflect#Type.MethodByName
m3: https://go.dev/ref/spec#Method_expressions

这些行为都是符合预期的,如果你不要 receiver 可以自己移除,如果你要 receiver 可以自己补充,哪种都可以
Qjues
2023-10-16 21:50:17 +08:00
@mcfog 了解了,我目前使用的方案就是手动将 receiver 传进去。感谢
Qjues
2023-10-16 21:50:43 +08:00
@mightybruce ok ,我研究研究
CodeCodeStudy
2023-10-17 09:05:51 +08:00
自定义的类型名称能不能不和关键字重复,看着难受
rickiey
2023-10-17 09:39:42 +08:00
Qjues
2023-10-17 10:00:06 +08:00
@CodeCodeStudy ---我只是想体现出这是一个 interface
Qjues
2023-10-17 10:01:05 +08:00
@rickiey get

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/982377

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX