"undefined" 在另一个文件中声明的函数?

"undefined" function declared in another file?

我正在尝试编写一个基本的 go 程序,该程序调用不同文件的函数,但属于同一包的一部分。然而,它 returns:

undefined: NewEmployee

这里是源代码:

main.go:

package main

func main() {
emp := NewEmployee()    
}

employee.go:

package main

type Employee struct {
    name string
    age int
}   

func NewEmployee() *Employee {
    p := &Employee{}
    return p
}

func PrintEmployee (p *Employee)  {
    return "Hello world!"
}

请阅读"How to Write Go Code"

在包目录中使用 go buildgo install,或提供包的导入路径。不要为 buildinstall.

使用文件参数

虽然您可以为 go run 使用文件参数,但您应该改为构建一个包,通常使用 go run .,但您几乎应该始终使用 go installgo build.

我刚刚在 GoLand(这是用于 Go 的 Intellij IDEA)中遇到了同样的问题并制定了解决方案。您需要将 Run kindFile 更改为 PackageDirectory。如果您进入 Run/Edit 配置,您可以从下拉菜单中选择它。

例如:对于包 ~/go/src/a_package,使用 a_packagePackage path~/go/src/a_packageDirectory 和 [=] 的 Run kind 12=] 或 Directory.

如果您的源文件夹是结构化的/go/src/blog(假设您的源文件夹的名称是博客)。

  1. cd /go/src/blog ...(在包含您的包的文件夹中 cd)
  2. 去安装
  3. 博客

那应该 运行 同时列出所有文件,而不是必须手动列出文件或 "bashing" 在命令行上使用方法。

如果您使用 go run,请执行 go run *.go。它会自动找到当前工作目录下的所有go文件,编译然后运行你的main函数

如果你想从另一个 go 文件调用一个函数并且你正在使用 Goland,那么从 运行 菜单中找到选项 'Edit configuration' 并从文件中更改 运行 种类到目录。它会清除所有错误并允许您从其他 go 文件调用函数。

您可以尝试以下方法之一:

方法一:

  • 假设你的项目名称是MyProject
  • 走你的路,运行go build
  • 它将创建一个可执行文件作为您的项目名称(“MyProject”)
  • 然后 运行 使用 ./MyProject
  • 的可执行文件

您可以通过键入 go build && ./MyProject 同时执行这两个步骤。 package main 的 Go 文件被编译为可执行文件。

方法二:

  • 只是 运行 go run *.go。它不会创建任何可执行文件,但它 运行s.

我 运行 遇到了与 Go11 相同的问题,只是想分享我是如何解决它的,以防万一他们 运行 遇到相同的问题。

我的 Go 项目 $GOPATH 之外,所以我不得不在没有打开此选项的情况下打开 GO111MODULE=on,它会给你这个问题;即使您尝试构建或测试整个 packagedirectory,没有 GO111MODULE=on

也无法解决

go run . 将 运行 您的所有文件。入口点是函数 main(),它对于 main 包来说必须是唯一的。

另一种选择是使用 go build 和 运行 构建二进制文件。

你应该使用 go modules now, if you are not following How to write go code

使用 go 模块,您不必将代码放在 $GOPATH/src 中。它也可以住在任何其他地方。

你可以将代码移动到不同的目录,比如/employee,让它工作在employee目录下初始化go模块

go mod init example.com/employee

虽然这并没有直接解决 OP 的具体问题,但我想我会配合我的“未定义”错误的解决方案:具有未定义方法的文件有一个 build constraint(构建标签).

更具体地说,我不小心包含了一个构建约束,用于从我部署的二进制文件使用的实用程序函数文件中删除我部署的应用程序二进制文件中的测试文件。因此,在 OP 的示例中 - 如果 employee.go 具有构建约束,则其 go build 命令将需要包含与约束匹配的 -tags 标志,以便包含文件。

有关详细信息,请阅读此博客 post: https://dave.cheney.net/tag/build-constraints

我花了一些时间来深入研究我自己的 MRE,所以希望它能对其他人有所帮助,尽管很简短:

如果您的函数/结构在具有 import "C" 的文件中定义,也会发生这种情况,如果 CGO_ENABLED=0 在你的 go 环境,导致你盯着两个文件包,不知何故无法在它们之间共享。

在 GoLand 中,

  • 右键单击目录
  • GoLand 将为您提供构建它的选项,运行它
  • 它还会为您创建一个运行配置草稿
  • 您可以使用右上角下拉选项进行保存

如果您右键单击一个文件,它会向您显示 运行、调试、测试该文件的命令。

如果您右键单击一个目录,该“包”将是相同的,期望目录中有一个 main.go 文件

题外话但还是:-)

之前:

func NewEmployee() *Employee {
    p := &Employee{}
    return p
}

之后:

func NewEmployee() *Employee {
    return &Employee{}
}

无需创建新变量。就 return.