有没有办法动态地收集给定结构类型的实例?

问题描述

我希望在程序的任何阶段,对给定包中定义的结构的所有实例执行操作。为了做到这一点,我考虑过开发一个收集这些实例的函数。但是我还没有发现任何东西。

为了阐明我的目标(在回答“ @Muffin Top”和“ @Volker”之后),我目前正在手动对每个程序包中的指针存储进行此注册。这种方法存在两个问题,注册是一项普通的任务,并且容易出错。

为使情况更清楚,请考虑具有一个结构foo的软件包FooFoo有一个string字段Name。该软件包还定义了两个Foo实例,分别声明为Foo1Foo2

package foo

type Foo struct {
    Name string
}

var Foo1,Foo2 = Foo{Name: "Foo1"},Foo{Name: "Foo2"}

我要实现的GetInstancesOfPkg如下例所示。要执行的操作仅是打印Name字段。

这是一个有效的示例,但其模型版本为GetInstancesOfPkg

package main

import (
    "log"
    "reflect"

    "github.com/thomaspeugeot/test-heapdump/foo"
)

func main() {

    s := GetInstancesOfPkg("github.com/thomaspeugeot/test-heapdump/foo")

    for _,instance := range s {
        // cast instance on foo.Foo
        if f,ok := instance.(*foo.Foo); !ok {
            log.Panic("Unknown Struct " + reflect.TypeOf(instance).Name())
        } else {
            log.Printf("Instance of Foo has name %s ",f.Name)
        }
    }
}

// GetInstancesOfPkg return a slice of instances of Struct defined in the package pkgPath
// --- this is the mockup verion ---
func GetInstancesOfPkg(pkgPath string) (interfaceSlice []interface{}) {

    var listOfFooInstances = []*foo.Foo{&foo.Foo1,&foo.Foo2}

    interfaceSlice = make([]interface{},len(listOfFooInstances))
    for i,d := range listOfFooInstances {
        interfaceSlice[i] = d
    }
    return
}

对于该解决方案,我知道reflect标准库或我所知道的任何其他库中都没有这样的功能。但是,我正在考虑:

  • 一种算法,它解析整个程序存储器,识别每个变量,获取其类型并收集与程序包的结构类型匹配的变量。由于delve和heapdump确实解析了整个内存,并且delve可以猜测变量类型,所以我有直觉可以实现所需的功能。我一直在尝试研究delve的工作方式或heapcoredump的开发方式,但这是一项太多的知识,无法吞噬达到预期的目标。

  • 另一种选择是添加一个预编译步骤,该步骤通过在每次变量初始化时添加注册来修改抽象语法树(AST)。

  • 我什至不确定go能否实现这种水平的反射(或者它是否可以携带?)

  • 性能不是问题,可以使用必需的wathever标志来编译程序,或者可以分析整个内存。

解决方法

有没有办法动态地收集给定结构类型的实例?

否。

您必须重新设计,例如通过记忆实例的函数分配实例。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...