如何在golang中列出一个包的公共方法?

huangapple go评论90阅读模式
英文:

How do I list the public methods of a package in golang

问题

如何在golang中列出包的公共方法?

main.go

package main

import (
	"fmt"
	"your-package-path/libs"
)

func main() {
	// 在这里列出所有的公共方法
	methods := []func(){
		libs.Resut1,
		libs.Resut2,
	}

	for _, method := range methods {
		method()
	}
}

libs/method.go

package libs

import "fmt"

func Resut1() {
	fmt.Println("method Result1")
}

func Resut2() {
	fmt.Println("method Result2")
}

main.go中,你可以通过导入包的方式来访问libs包中的公共方法。然后,你可以将这些公共方法存储在一个函数切片中,并在main函数中遍历并调用它们。这样就可以列出包的公共方法了。

英文:

How to list the package's public methods in golang?

main.go

package main

func main() {
// list all public methods in here
}

libs/method.go

package libs

func Resut1() {
    fmt.Println("method Result1")
}

func Resut2() {
    fmt.Println("method Result2")
}

答案1

得分: 9

我不能以100%的确定性回答,但我认为在Go语言中不可能完全按照描述的方式实现这个功能。这个讨论比较旧,但它描述了基本的问题 - 只是导入一个包并不能保证包中的任何方法实际存在。编译器实际上会尝试删除包中的每个未使用的函数。因此,如果你在另一个包中有一组"Result*"方法,除非它们已经被使用,否则在调用程序时这些方法实际上并不存在。

此外,如果你查看一下runtime反射库,你会注意到缺乏任何形式的包级别分析。

根据你的使用情况,可能仍然有一些事情可以做。如果你只是想静态分析你的代码,你可以解析一个包并获取文件中所有函数声明的完整范围,像这样:

import (
	"fmt"
	"go/ast"
	"go/parser"
	"go/token"
    "os"
)

const subPackage := "sub"

func main() {
	set := token.NewFileSet()
	packs, err := parser.ParseDir(set, subPackage, nil, 0)
	if err != nil {
		fmt.Println("Failed to parse package:", err)
        os.Exit(1)
	}

	funcs := []*ast.FuncDecl{}
	for _, pack := range packs {
		for _, f := range pack.Files {
			for _, d := range f.Decls {
				if fn, isFn := d.(*ast.FuncDecl); isFn {
					funcs = append(funcs, fn)
				}
			}
		}
	}

	fmt.Printf("all funcs: %+v\n", funcs)
}

这将以ast.FuncDecl的形式获取所述子包中的所有函数声明。这不是可调用的函数;它只是它的源代码的表示。

如果你想要调用这些函数,你需要做一些更复杂的操作。在收集这些函数之后,你可以将它们汇总并输出一个单独的文件来调用每个函数,然后运行生成的文件。

英文:

I can't answer with a 100% confidence, but I don't think this is possible to do in Go, at least quite as described. This discussion is rather old, but it describes the basic problem - just importing a package doesn't guarantee that any methods from the package are actually there. The compiler actually tries to remove every unused function from the package. So if you have a set of "Result*" methods in another package, those methods won't actually be there when you call the program unless they are already being used.

Also, if take a look at the runtime reflection library, you'll note the lack of any form of package-level analysis.


Depending on your use case, there still might be some things you can do. If you just want to statically analyze your code, you can parse a package and get the full range of function delcarations in the file, like so:

import (
	"fmt"
	"go/ast"
	"go/parser"
	"go/token"
    "os"
)

const subPackage := "sub"

func main() {
	set := token.NewFileSet()
	packs, err := parser.ParseDir(set, subPackage, nil, 0)
	if err != nil {
		fmt.Println("Failed to parse package:", err)
        os.Exit(1)
	}

	funcs := []*ast.FuncDecl{}
	for _, pack := range packs {
		for _, f := range pack.Files {
			for _, d := range f.Decls {
				if fn, isFn := d.(*ast.FuncDecl); isFn {
					funcs = append(funcs, fn)
				}
			}
		}
	}

	fmt.Printf("all funcs: %+v\n", funcs)
}

This will get all function delcarations in the stated subpackage as an ast.FuncDecl. This isn't an invokable function; it's just a representation of the source code of it.

If you wanted to do anything like call these functions, you'd have to do something more sophisticated. After gathering these functions, you could gather them and output a separate file that calls each of them, then run the resulting file.

huangapple
  • 本文由 发表于 2017年1月13日 15:18:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/41629293.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定