简体   繁体   English

从 golang 中的 package 获取导出函数列表

[英]Getting list of exported functions from a package in golang

Let's say I have some package假设我有一些 package

// ./somepkg/someFile.go
package somepkg
import "fmt"
func AnExportedFunc(someArg string) {
    fmt.Println("Hello world!")
    fmt.Println(someArg)
)

and I import it from my main go file我从我的主 go 文件中导入它

// ./main.go
package main
import (
    "./somepkg" // Let's just pretend I have the full path written out
    "fmt"
)

func main() {
    fmt.Println("I want to get a list of exported funcs from package 'somefolder'")
}

Is there a way to get access to the exported functions from package 'somepkg' and then to consequently call them?有没有办法从 package 'somepkg' 访问导出的函数,然后调用它们? Argument numbers/types would be consistent across all functions in somepkg.参数编号/类型在 somepkg 中的所有函数中都是一致的。 I've looked through the reflection package but I'm not sure if I can get the list and call the functions without knowing any information other than package name.我查看了反射 package 但我不确定是否可以在不知道 package 名称以外的任何信息的情况下获取列表并调用函数。 I may be missing something from the godocs however, so any advice is appreciated.但是,我可能会从 godocs 中遗漏一些东西,所以任何建议都值得赞赏。 What I'm trying to do is essentially have a system where people can drop in.go files as a sort of "plugin".我想要做的基本上是有一个人们可以加入的系统。go 文件作为一种“插件”。 These "plugins" will have a single exported function which the main program itself will call with a consistent number and types of args.这些“插件”将有一个导出的 function,主程序本身将使用一致的数量和类型的参数调用它。 Access to this codebase is restricted so there are no security concerns with arbitrary code execution by contributors.对该代码库的访问受到限制,因此贡献者的任意代码执行不存在安全问题。

Note: This is all compiled so there are no runtime restrictions注意:这是全部编译的,因此没有运行时限制

What I'm trying to do is something like this if written in python如果用 python 编写,我想做的是这样的

# test.py
def abc():
    print "I'm abc"

def cba():
    print "I'm cba"

and

# foo.py
import test
flist = filter(lambda fname: fname[0] != "_", dir(test))

# Let's forget for a moment how eval() is terrible
for fname in flist:
    eval("test."+fname+"()")

running foo.py returns运行 foo.py 返回

I'm abc
I'm cba

Is this possible in golang?这在golang中可能吗?

Edit:编辑:

I should note that I have already "accomplished" this with something very similar to http://mikespook.com/2012/07/function-call-by-name-in-golang/ but require that each additional "plugin" add its exported function to a package global map.我应该注意到,我已经用与http://mikespook.com/2012/07/function-call-by-name-in-golang/非常相似的东西“完成”了这一点,但要求每个额外的“插件”添加它的将 function 导出到 package 全局 map。 While this "works", this feels hacky (as if this whole program isn't... lol;) and would prefer if I could do it without requiring any additional work from the plugin writers.虽然这“有效”,但这感觉很hacky(好像整个程序不是......大声笑;)并且如果我可以在不需要插件编写者的任何额外工作的情况下完成它,我会更喜欢。 Basically I want to make it as "drop and go" as possible.基本上我想让它尽可能地“放下就走”。

The easiest way to do this is to use the template library to parse your code and insert the new package name where appropriate. 最简单的方法是使用模板库来解析代码,并在适当的地方插入新的程序包名称。

Playground 操场

You can use this by loading all of the finals where you call the user package and then output the generated file to the execution directory. 您可以通过在调用用户包的所有决赛中加载所有总决赛,然后将生成的文件输出到执行目录来使用此功能。

As you might've guessed, it is difficult to achieve in Go, if not impossible, as Go is a compiled-language.正如您可能已经猜到的那样,在 Go 中很难实现,如果不是不可能的话,因为 Go 是一种编译语言。

Traversing a package for exported functions can only get you the list of functions.exported functions遍历 package 只能得到函数列表。 A sample for this is: Playground .一个示例是: Playground This is a AST (Abstract Syntax Tree) method which means calling the functions dynamically is not possible, or requires too much of workarounds.这是一种 AST(抽象语法树)方法,这意味着动态调用函数是不可能的,或者需要太多的变通方法。 Parsing function name string as function type doesn't work here.将 function 名称字符串解析为 function 类型在这里不起作用。

Alternatively, you can use try methods by binding the exported functions to some type.或者,您可以通过将导出的函数绑定到某种类型来使用 try methods

type Task struct {}
func (Task) Process0()
func (Task) Process1(v int)
func (Task) Process2(v float64)
func (Task) Process3(v1 bool, v2 string)

This totally changes the way we operate as the 4 methods are now associated with a type Task and we can pass empty instance of Task to call the methods defined on it.这完全改变了我们的操作方式,因为这 4 个方法现在与类型Task相关联,我们可以传递Task的空实例来调用其上定义的方法。 This might look like just another workaround, but is very common in languages like Go.这可能看起来只是另一种解决方法,但在 Go 等语言中非常常见。 A sample for this in Playground which actually works as expected. Playground中的一个示例,它实际上按预期工作。


In both the examples, I've used multiple files in playground.在这两个示例中,我在 Playground 中使用了多个文件。 If you are not familiar with this structure, just create your workspace in your local as following and copy the code under each file name from playground:如果您不熟悉此结构,只需在本地创建工作区,如下所示,然后从 Playground 复制每个文件名下的代码:

<Your project>
├── go.mod
├── main.go
└── task
    └── task.go

References:参考:

  1. How to dynamically call all methods of a struct in Golang? 如何在 Golang 中动态调用结构的所有方法? [duplicate] [复制]
  2. How to inspect function arguments and types [duplicate] 如何检查 function arguments 和类型 [重复]
  3. How do I list the public methods of a package in golang [duplicate] 如何在golang中列出package的公共方法[重复]
  4. Abstract Syntax Tree - Wiki抽象语法树 - Wiki
  5. Functions vs Methods in Go Go 中的函数与方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从另一个 package 导出的函数 - Exported functions from another package 找不到模块:包路径。 不从包中导出 - Module not found: Package path . is not exported from package firebase 函数部署错误:ERR_PACKAGE_PATH_NOT_EXPORTED - firebase functions deploy error : ERR_PACKAGE_PATH_NOT_EXPORTED Firebase 错误:找不到模块:错误:包路径。 不从包中导出 - Firebase Error : Module not found: Error: Package path . is not exported from package 找不到模块:错误:Package 路径。 不从 package 导出 - Module not found: Error: Package path . is not exported from package Firebase 错误:找不到模块:错误:Package 路径。 不从 package 导出 - Firebase Error : Module not found: Error: Package path . is not exported from package 在 Golang SDK 中获取 Azure 位置列表的问题 - Problems with getting list of locations of Azure in Golang SDK 无法在 firebase 函数上运行 mocha 测试,[ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './lib/encoder' is not defined by "exports" - Unable to run mocha tests on firebase-functions, [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './lib/encoder' is not defined by "exports" 处理来自 Golang 列表的循环中的 nil - Handle nil in loop from list Golang (Golang) 处理和格式化列表中的 nil - (Golang) handle and format nils from list
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM