(请参阅底部的2019更新)
警告 :未经测试且骇客。每当发布新版本的Go时可能会中断。
通过对Go的运行时进行一些修改,可以获得运行时知道的所有类型。在您自己的程序包中包含一个小的程序集文件,其中包含:
TEXT yourpackage·typelinks(SB), NOSPLIT,yourpackage-0 JMP reflect·typelinks(SB)
在中
func typelinks() []*typeDefDummy,声明函数原型(无主体):
type typeDefDummy struct { _ uintptr// padding _ uint64 // padding _ [3]uintptr // padding StrPtr *string}
除了类型定义:
yourpackage
然后只需调用typelinks,遍历切片并读取每个StrPtr作为名称。寻找那些以开头的人
yourpackage。请注意,如果有两个
d在不同路径中调用的包,则此方法将不会明确工作。
我可以以某种方式挂接到反射包中以实例化这些名称的新实例吗?
是的,假设
*typeDefDummy是type的值
t := reflect.TypeOf(*(*interface{})(unsafe.Pointer(&d)))(请注意星号,非常重要):
t
现在
reflect.Type是一个
reflect.Value可以实例化
$GOPATH/src/tl/tl.gos的值。
编辑:我测试并成功执行了此代码,并已将其作为要点上传。
调整软件包名称,并根据需要添加路径。
更新2019自从我最初发布此答案以来,发生了很多变化。这是对如何在2019年使用Go 1.11进行相同 *** 作的简短描述。
package tlimport ( "unsafe")func Typelinks() (sections []unsafe.Pointer, offset [][]int32) { return typelinks()}func typelinks() (sections []unsafe.Pointer, offset [][]int32)func Add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer { return add(p, x, whySafe)}func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer
$GOPATH/src/tl/tl.s
TEXT tl·typelinks(SB),main.go-0 JMP reflect·typelinks(SB)TEXT tl·add(SB),package mainimport ( "fmt" "reflect" "tl" "unsafe")func main() { sections, offsets := tl.Typelinks() for i, base := range sections { for _, offset := range offsets[i] { typeAddr := tl.Add(base, uintptr(offset), "") typ := reflect.TypeOf(*(*interface{})(unsafe.Pointer(&typeAddr))) fmt.Println(typ) } }}-0 JMP reflect·add(SB)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)