有没有办法检查Go中是否存在func?
在PHP中我可能会做类似
的事情if(function_exists('someFunction')) {
//...
}
但是我还没有弄清楚如何在Go
中做到这一点对此的任何帮助都将受到极大的欢迎。
答案 0 :(得分:6)
关于你想要做什么的更多背景会有所帮助。 正如您在自己的注释中所述,如果您尝试调用函数,则在编译时进行Go检查(如果函数存在),大多数情况下都是。
我想到的一个例外是,当您使用interface{}
并且想要在调用方法之前检查方法是否存在时。为此,您可以使用类型检查。
示例:
package main
import "fmt"
// a simple Greeter struct
// with a Hello() method defined
type Greeter struct {
Name string
}
func (m *Greeter) Hello() string {
return "hello " + m.Name
}
var x interface{}
func main() {
x = Greeter {Name:"Paolo"} // x is a interface{}
g,ok := x.(Greeter) // we have to check that x is a Greeter...
if ok {
fmt.Println(g.Hello()) // ...before being able to call Hello()
}
}
我能想到的另一个场景是你正在为Go创建自己的工具,需要在编译之前解析go文件。如果是这样,Go会为parser package
提供帮助答案 1 :(得分:2)
没有办法做到这一点(并且为了好!)。原因是Go是一种编译语言,并且不支持可加载模块(至少),因此函数不能在运行时来去,因此无论顶级函数是否存在,您都知道定义:给定源文件import
包含感兴趣的函数 1 的包,该函数在此源文件中可见。或者此函数在此源文件所属的同一个包中声明,因此它也可用。在所有其他情况下,该功能不可用。请注意,函数可能在程序中编译,但在编译时仍然在给定的源文件中不可见,因此在Go中不存在可见性的整体定义。
另一方面,你可能需要一些普遍性。 Go中的一般性是通过interfaces实现的。您可以定义一个接口,然后需要一个类型来实现它。检查类型是否实现了接口是通过a neat trick完成的。
1 没有将该模块重命名为空,但我们现在暂不触及。
答案 2 :(得分:1)
提供的东西是接口值,键入assert,如下所示:
if Aer, ok := thing.(interface{MethodA()}); ok {
Aer.MethodA()
}
如果事物是结构,请首先将其分配给接口变量, 因为类型断言仅适用于接口值。
定义命名接口而不使用 随机数,但是对于像这样的简单情况,这是不值得的。
答案 3 :(得分:0)
这听起来很像XY problem。请告诉你要做什么。据我所知,这是你不能像在PHP中那样做的事情。
但是,您可以创建一个功能名称为键的地图。手动添加函数或通过在编译之前或运行时解析源文件来生成内容。解析源代码似乎是一个肮脏的黑客。