Golang Go语言 反射问题,从接口反射方法

发布于 1周前 作者 h691938207 来自 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

10 回复

有没有什么其他的方案呢,通过接口可以分析出每个方法的完整类型。

更多关于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 ,我研究研究

自定义的类型名称能不能不和关键字重复,看着难受

—我只是想体现出这是一个 interface

在Go语言中,反射(reflection)是一种强大的工具,允许程序在运行时检查和操作变量的类型、值和方法。对于接口类型的变量,反射机制同样适用,并且可以通过反射调用接口实现的方法。

当你有一个接口类型的变量时,可以使用reflect.ValueOfreflect.TypeOf函数来获取其值和类型信息。为了调用接口的方法,你需要先获取到接口变量的reflect.Value,然后使用MethodByName方法获取到具体的方法对象,最后通过Call方法调用该方法。

需要注意的是,通过反射调用方法时,需要传递正确类型和数量的参数。参数需要是[]reflect.Value类型,返回值也是[]reflect.Value类型。如果方法没有返回值,那么返回的切片将是空的。

此外,由于反射操作相对复杂且容易出错,通常建议仅在必要时使用反射,例如在编写通用的库或框架时。在普通的应用程序中,更推荐使用显式的类型和方法调用,以提高代码的可读性和可维护性。

最后,需要注意的是,反射操作可能会带来一定的性能开销,因此在性能敏感的场景中需要谨慎使用。

总之,Go语言的反射机制为处理接口提供了灵活而强大的手段,但也需要开发者在使用时仔细考虑其可能带来的复杂性和性能影响。

回到顶部