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

247

我想编写一个基本的Go程序,该程序调用同一软件包中不同文件中的函数。 但是,它返回:

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!"
}

13
你是否在使用go run命令?(详情请参考http://golang.org/doc/code.html) - JimB
1
@JuanM,我的问题是main.goemployee.go的源代码是否完整?因为所有的Go文件都应该有一个包语句,而我在你的代码中没有看到。请参见:https://golang.org/doc/code.html#PackageNames - Chris Pfohl
1
employee.go 的最后一个函数是错误的(没有函数名称,也没有声明返回类型)。虽然这不是你要求解决的问题,但它表明还有更多的问题。你能否发布完整的代码和编译时的完整错误信息? - siritinga
1
然后展示你正在做什么!GOPATH,实际代码以及如何调用“go”工具。 - JimB
%GOPATH% C:\gocode\src文件 Employee.go 和 main.go 存放在 C:\gocode\src 目录下。 - Juan M
显示剩余5条评论
14个回答

285
请阅读"如何编写Go代码"。 在包目录中使用go buildgo install,或为包提供导入路径。不要使用文件参数进行buildinstall。 虽然您可以使用文件参数来运行go run,但最好还是构建一个包,通常使用go run .,但几乎总是使用go installgo build

感谢您的输入,@JimB!我编辑了环境变量(我也忘记设置GOBIN),将我的文件移动到正确的位置,但是当我尝试go install时仍然出现相同的错误。有什么建议吗? - Juan M
你确定没有其他错误吗?你的employee.go文件无法直接编译。否则,我需要确切地了解你正在做什么。包括准确的路径、调用等信息。 - JimB
同时运行 go run . - 这里的句点表示“当前目录”。 - Kyle Mcgill
4
go run *.go 这种方式并不好,因为如果代码中有任何构建限制或测试文件,它都会出问题。 - Jonathan Hall

128

我在GoLand中遇到了同样的问题(它是适用于Go的Intellij IDEA),并找到了解决方案。您需要将运行类型文件更改为目录。如果您进入运行/编辑配置,可以从下拉菜单中选择。

例如:对于包~/go/src/a_package,请使用包路径 a_package目录 ~/go/src/a_package,并将运行类型设置为目录


10
谢谢,这正是我所需要的。请注明你的回答与Intellij IDEA有关。 - kivagant
我希望这个默认能够更靠近顶部显示。这是一个非常有价值的答案。 - Shadoninja
这解决了我在IDEA中的问题。 - hukeping
1
只是为了澄清,您需要进入菜单并选择“运行”->“运行...”->“编辑配置...”,然后您将看到“运行类型”。对我来说,“目录”解决了问题。而“包”则会给我带来其他错误,谢谢。 - E235

55

如果你正在使用go run命令,请输入go run *.go。它会自动查找当前工作目录中的所有go文件,编译并运行你的主函数。


1
这种做法有什么缺点吗?这似乎是对OP问题最简单的回答。 - Stavros_S
1
在Bash下的更通用的解决方案:go run !(*_test).go -- Golang:通过命令行运行当前目录中所有.go文件(多文件包) - Brent Bradburn

19

go run . 命令将运行所有文件。入口点是函数 main(),它必须唯一属于main包。

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


2
我已经有一段时间没有运行我的旧Go项目了,也忘记了如何运行。最终在您的答案中找到了它。这应该是一个被点赞的答案! - mununki

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

方法1:

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

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

方法2:

  • 只需运行go run *.go 。 它不会创建任何可执行文件但会直接运行。

5

如果你想从另一个go文件中调用函数,并且正在使用Goland,则需要从运行菜单中找到“编辑配置”选项,将运行类型从文件更改为目录。这将清除所有错误并允许你从其他go文件中调用函数。


4

如果您没有遵循如何编写 Go 代码,现在应该使用Go 模块。使用 Go 模块后,您不必将代码放在 $GOPATH/src 中,它也可以存储在其他任何位置。

您可以将代码移动到不同的目录,例如 /employee,在 employee 目录下初始化 Go 模块即可使其正常工作。

go mod init example.com/employee

2

我在我的Go文件中遇到了一个讨厌的import "C"


1

我也遇到了使用Go11时的相同问题,想分享一下我是如何解决这个问题的,以帮助其他人遇到同样的问题。

我的Go项目在$GOPATH之外,所以我必须打开GO111MODULE=on选项,如果没有打开这个选项,它会给你报错;即使你尝试构建或测试整个packagedirectory,也无法解决这个问题,除非你打开了GO111MODULE=on选项。


1
虽然这并没有直接解决 OP 的具体问题,但我认为我可以提供一个解决我的“未定义”错误的方法:具有未定义方法的文件中有一个 build constraint(构建标记)。
更具体地说,我不小心在我的部署二进制应用程序中使用的实用函数文件中包含了一个构建约束,以从我的测试文件中删除测试文件。因此,在 OP 的示例中 - 如果 employee.go 有一个构建约束,他们的 go build 命令需要包括一个与约束匹配的 -tags 标志,才能包含该文件。
有关更多信息,请阅读此博客文章: https://dave.cheney.net/tag/build-constraints

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接