Golang Go语言 反射问题,从接口反射方法
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 个,缺少接口本身
通过第三种方案反射出来的方法,结果符合预期,但是需要每个方法都硬编码。
Golang Go语言 反射问题,从接口反射方法
更多关于Golang Go语言 反射问题,从接口反射方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
有没有什么其他的方案呢,通过接口可以分析出每个方法的完整类型。
更多关于Golang Go语言 反射问题,从接口反射方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
建议直接去看 uber 用反射写的 AOP 控制反转是如何实现。
https://github.com/uber-go/dig
https://github.com/uber-go/fx
m1,m2: https://pkg.go.dev/reflect#Type.MethodByName
m3: https://go.dev/ref/spec#Method_expressions
这些行为都是符合预期的,如果你不要 receiver 可以自己移除,如果你要 receiver 可以自己补充,哪种都可以
了解了,我目前使用的方案就是手动将 receiver 传进去。感谢
ok ,我研究研究
自定义的类型名称能不能不和关键字重复,看着难受
get
在Go语言中,反射(reflection)是一种强大的工具,允许程序在运行时检查和操作变量的类型、值和方法。对于接口类型的变量,反射机制同样适用,并且可以通过反射调用接口实现的方法。
当你有一个接口类型的变量时,可以使用reflect.ValueOf
和reflect.TypeOf
函数来获取其值和类型信息。为了调用接口的方法,你需要先获取到接口变量的reflect.Value
,然后使用MethodByName
方法获取到具体的方法对象,最后通过Call
方法调用该方法。
需要注意的是,通过反射调用方法时,需要传递正确类型和数量的参数。参数需要是[]reflect.Value
类型,返回值也是[]reflect.Value
类型。如果方法没有返回值,那么返回的切片将是空的。
此外,由于反射操作相对复杂且容易出错,通常建议仅在必要时使用反射,例如在编写通用的库或框架时。在普通的应用程序中,更推荐使用显式的类型和方法调用,以提高代码的可读性和可维护性。
最后,需要注意的是,反射操作可能会带来一定的性能开销,因此在性能敏感的场景中需要谨慎使用。
总之,Go语言的反射机制为处理接口提供了灵活而强大的手段,但也需要开发者在使用时仔细考虑其可能带来的复杂性和性能影响。