V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
Qjues
V2EX  ›  Go 编程语言

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

  •  
  •   Qjues · 194 天前 · 1102 次点击
    这是一个创建于 194 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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 个,缺少接口本身

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

    9 条回复    2023-10-17 10:01:05 +08:00
    Qjues
        1
    Qjues  
    OP
       194 天前
    有没有什么其他的方案呢,通过接口可以分析出每个方法的完整类型。
    mightybruce
        2
    mightybruce  
       194 天前
    建议直接去看 uber 用反射写的 AOP 控制反转是如何实现。
    https://github.com/uber-go/dig
    https://github.com/uber-go/fx
    mcfog
        3
    mcfog  
       194 天前
    m1,m2: https://pkg.go.dev/reflect#Type.MethodByName
    m3: https://go.dev/ref/spec#Method_expressions

    这些行为都是符合预期的,如果你不要 receiver 可以自己移除,如果你要 receiver 可以自己补充,哪种都可以
    Qjues
        4
    Qjues  
    OP
       194 天前
    @mcfog 了解了,我目前使用的方案就是手动将 receiver 传进去。感谢
    Qjues
        5
    Qjues  
    OP
       194 天前
    @mightybruce ok ,我研究研究
    CodeCodeStudy
        6
    CodeCodeStudy  
       193 天前
    自定义的类型名称能不能不和关键字重复,看着难受
    rickiey
        7
    rickiey  
       193 天前
    Qjues
        8
    Qjues  
    OP
       193 天前
    @CodeCodeStudy ---我只是想体现出这是一个 interface
    Qjues
        9
    Qjues  
    OP
       193 天前
    @rickiey get
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2824 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 15:00 · PVG 23:00 · LAX 08:00 · JFK 11:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.