如何通过命令行运行当前目录下所有的.go文件(多文件包)

86

我是Go的新手,非常喜欢这种语言,但很快意识到由于程序规模增加,我需要开始分割我的文件。

go run main.go(其中main.go是我的主函数文件)

不起作用,我遭遇了障碍,因为我不知道如何让我的程序运行起来。

通过一些快速搜索,我找到了答案:

go run main.go other.go ..

通过键入所有package main包含的文件,我可以让程序运行。 但是,每次都这样做非常麻烦和令人沮丧。

我编写了以下自问自答的问题,以防止像我这样的其他人再次遇到此障碍。

13个回答

112

但是当我的工作目录不是也不能是 . 时,我该怎么做呢? - Zyl
1
"." 只是当前目录的占位符。你可以用任何其他路径来替换它。 - Macilias
当存在多个文件中的“package main”时,就会出现这种情况,那么你不能简单地运行例如“go run main.go”或“go run app.go”,你需要运行“go run .” === “go run file1.go file2.go file3.go…” === “go run *.go”。感谢您提供的答案。非常有启发性的时刻! - shellyyg

76
如下所示:

正如Nate Finch所指出的:

Go run只适用于非常小的程序,通常只需要一个单独的文件。

即使在Unix上,go run *.go也经常不正确。在任何带有单元测试的项目中(每个项目都应该有单元测试),这将会产生错误:

go run: cannot run *_test.go files (something_test.go)

它也会忽略构建限制,因此在Unix上编译(或试图编译)_windows.go文件,这不是您想要的。

已经有一些讨论,让 go run 像其他 go 命令一样工作,并且有一个开放的CL (5164)。目前正在考虑在Go 1.4中使用。与此同时,在所有平台上推荐的解决方案是:

go build && ./<executable>

26

你可以使用以下bash命令来运行所有.go文件,但不包含测试文件:

go run $(ls -1 *.go | grep -v _test.go)

5
这个答案应该被采纳。它解决了*nix开发者的问题。 - MusikPolice
1
我喜欢这个,但是当它被设置为别名时,命令的表现并不好。r.sendecky的解决方案使用shopt!(...)非常有效。 - cody

26

Unix相关系统

在大多数情况下,go run *.go就已经足够了。

如果出现错误,请使用以下方法:

Windows系统(以及其他一些go run *.go无法工作的情况)

在Windows命令行中,标记扩展不起作用,因此上述方法将无法正常工作并显示错误。 在某些情况下,由于当前编译器的限制,go run *.go也可能无法在操作系统中正常工作。

在这些情况下,请使用

go build && foo.exe

其中foo.exe是生成的.exe文件的名称。 如果您不知道可执行文件的名称,请首先运行

go build然后检查生成的.exe文件的名称。 然后使用包括文件名的方法.

这两种方法将构建并运行当前目录中的所有.go文件,而不需要太多麻烦。


如何在子文件夹中运行*.go文件? - Yi Jiang
如果您使用的是Windows PowerShell,则应该输入以下命令:go build; .\foo.exe(而不是&&,您需要使用分号(点和逗号))。 - OWADVL
有没有一种跨平台的方法,使得 filepath.Abs(filepath.Dir(os.Args[0])) 不是临时目录? - Polv

19

最好的方法是这样运行:

go run !(*_test).go

它会跳过所有测试文件,这正是您需要避免错误的方法。

另一个建议:

go build && ./<executable>

这有点烦人。你不得不一直删除可执行文件以避免被 Git 标记。当然,你可以将其放入 gitignore 中,但是我很懒,这需要额外的步骤。


3
您需要先运行shopt -s extglob来启用!(...)通配符语法。 - Johnny Wong
工作得很好,但是在bash文件中却出了一些问题,我想可能是有一些不支持的字符。 - Christophe Vidal

8
如果我理解你的问题正确,你需要将其他代码作为库导入。
小例子:
./testing/main.go:
package main

import "fmt"
import L "testing/lib"

func main() {
    fmt.Println("Hello from main()")
    L.Somefunc()
}

./testing/lib/somelib.go:

package lib

import "fmt"

func Somefunc() {
    fmt.Println("Hello from Somefunc()")
    return
}

启动命令 - go run main.go


1
这是针对Windows开发人员的正确答案。在我的情况下,我必须使用完全限定路径 import "github.com/abacaj/hello/lib",然后像这样使用它 sc := new(lib.ServiceControl) - AntonB

4

只需使用这个

go run *.go 

假设您没有任何测试文件,它将正常工作。

这绝对是我在寻找的东西!谢谢! - Macilias
4
不能在Windows上运行。CreateFile *.go: 文件名、目录名或卷标语法不正确。 - Nato Boram
但现在,我们可以直接使用 go run . :) - Macilias
如果有任何测试文件,它将无法工作。最好使用 go run . - Sajidur Rahman
1
是的,它可以在Windows上运行。只需使用Git Bash即可。 - Omar Omeiri

3
如果您在Windows上的Vscode终端中运行且不了解工作区,则可以按照以下步骤操作:
go run $(ls *.go)

2

这是我的解决方案:

go run $(find . -name "*.go" -and -not -name "*_test.go" -maxdepth 1)

我使用别名来方便地运行命令行应用程序。
alias gorun='go run $(find . -name "*.go" -and -not -name "*_test.go" -maxdepth 1)'

$ gorun param1 param2

1
在Windows上,我通常只需在所有项目目录中添加一个小的test.bat文件:
go build
.\{project_name}.exe
go clean

足够好用。当然,将{project_name}替换为您的可执行文件名。一旦可执行文件完成,批处理脚本就会继续进行清理工作。

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