Golang项目中能否创建多个main.go文件?

Golang项目中能否创建多个main.go文件? 在实际项目中我通常只会创建一个main.go文件,但现在我正在通过大量动手编码来学习Go语言,所以想知道是否可以在不同文件夹下创建多个main.go文件,这样便于我在一个地方学习所有代码?

在实际项目中,我可以创建多个main.go文件吗? 最佳实践是什么?

谢谢

14 回复

可以将它们放在同一个文件夹中。我个人经常这样做,因为我有很多只包含单个文件的文件夹。

更多关于Golang项目中能否创建多个main.go文件?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


是的,但不在同一路径(不在同一文件夹中)

我使用 JetBrains 的 GoLand,当我尝试在同一个文件夹中添加两个 main.go 文件时,它报错: “文件已存在。”

是的,这完全没问题。对于 go buildgo run 命令,你只需提供想要编译的主文件的路径即可。

func main() {
    fmt.Println("hello world")
}

根据我的理解,我可以按照以下方式构建项目:

projects
-----cmd
----------cmd1
-----------------main.go
-----------------others.go
----------cmd2
-----------------main.go
-----------------others.go
....

这样对吗?

当然,当您将它们放在同一个文件夹中时,不能给它们相同的名称,但您可以给它们取不同的名称,只要它们都包含 package main 和一个 main() 函数即可。

是的,只要在同一个包下,允许使用不同的文件名。我想我可能没有正确理解问题,我认为他问的是同一个文件夹下有两个 main.go 文件(同名文件)的情况。 ……抱歉

@Nobbz 的回答基础上补充一些内容,你可以参考这个项目结构(虽然不是 Go 语言的严格规定,但可以作为参考):https://github.com/golang-standards/project-layout。你应该会对 /cmd 目录感兴趣。

jameswang2015:

看起来也包含了依赖项(在这个例子中是 pkg/pkg1 下的 addition.go)。对吗?

是的,它确实在你的主程序中成功导入了 pkg/pkg1。太棒了! 😄

请注意,pkg 目录中的任何内容都可以放在独立的代码仓库中。因此,你不必将所有内容都塞进同一个代码库中。

jameswang2015:

所以,根据我的理解,我可以按照以下方式构建项目:

jameswang2015:

这样对吗?

是的,类似这样。你可以用确切的程序名来命名 cmd1cmd2

我建议你采用这样的结构:

repo
  +----cmd
  |     +----- cmd1
  |     |        +------ main.go
  |     |
  |     +----- cmd2
  |              +------ main.go
  |
  +----others.go
  +----libs.go
  +---- ...

这样设计的理念是让 main 包尽可能保持简洁,同时将函数和库代码保留在代码库中。通过这种方式,你的代码库仍然可以被任何 cmd 主代码以及外部代码 import

如果有疑问,欢迎参考这个项目结构

感谢所有的回复,很抱歉我回复晚了——白天工作太忙了。

我尝试在同一个文件夹下创建了两个go文件,每个文件都包含package mainfunc main()

在这个文件夹中,当我运行go build时,出现了一些报错信息:

(base) zwang-mac:cmd1 zwang$ go build
# _/Users/zwang/GolandProjects/learngo/cmd/cmd1
./race.go:14:6: main redeclared in this block
        previous declaration at ./main.go:10:6

而且没有生成任何二进制文件。但是当我为每个go文件单独执行go build时,比如:

go build main.go
go build race.go

它确实成功地为每个文件生成了二进制文件。所以我想问的是,在这种情况下为什么go会对不指定go文件的go build命令报错?

谢谢

我正在尝试理解However, it does not include dependencies so when you do that这句话。所以构建了这样的目录结构:

learngo
+-------cmd
|            +--------cmd2
|             |            +-----------main.go
+-------pkg
|             +--------pkg1
|              |            +----------addition.go

这是我的main.go文件:

package main

import "fmt"
import "learngo/pkg/pkg1"

func main(){
	fmt.Println("hello")
	fmt.Println(pkg1.Addition(2, 3))
}

这是我的addition.go文件:

package pkg1

func Addition(a int, b int) int{
	return a + b
}

在cmd/cmd2目录下,我执行了go build main.go命令,它生成了二进制文件’main’,当我运行它时确实按预期输出了5。所以我认为使用go build main.go命令时,看起来也包含了依赖项(在这个例子中就是pkg/pkg1目录下的addition.go)。是这样吗?

它不会创建任何二进制文件。但是当我为每个 Go 文件执行 go build 时,比如:

go build main.go
go build race.go

它确实成功为每个文件生成了二进制文件。所以我认为我的问题是,在这种情况下为什么 Go 会对不指定 Go 文件的 go build 命令报错

原因在于当没有向 go build 提供文件名时,它会将给定命令视为构建包(go build .)。编译器会同时看到 main.gorace.go,但它不知道您希望使用哪个 func main()。因此,它会提示其中一个被重复声明。

Go 允许单独构建单个脚本,这就是为什么您可以独立构建每个文件。但是,这样做时不会包含依赖项。

我尝试在同一文件夹下创建两个 Go 文件,每个文件都有 package mainfunc main()

实际上,一个文件夹应该只包含一个 package main 和一个 func main()。您可以在代码仓库中创建任意数量的 main 文件夹。

作为实践,您可以将这些 main 文件夹统一打包在一个名为 cmd/ 的目录下。这里有一个示例:golangci-lint/cmd at master · golangci/golangci-lint · GitHub

在Go项目中,可以在不同目录下创建多个main.go文件,每个目录代表一个独立的可执行程序。Go语言要求每个可执行程序必须有自己的main包和main函数,且位于独立的目录中。

示例项目结构:

myproject/
├── app1/
│   └── main.go
├── app2/
│   └── main.go
└── shared/
    └── utils.go

示例代码:

app1/main.go

package main

import "fmt"

func main() {
    fmt.Println("Running App 1")
}

app2/main.go

package main

import "fmt"

func main() {
    fmt.Println("Running App 2")
}

构建和运行:

# 构建 app1
go build -o app1 app1/main.go

# 构建 app2  
go build -o app2 app2/main.go

# 运行
./app1
./app2

关键要点:

  1. 每个main.go必须在单独的目录中
  2. 每个必须声明package main
  3. 每个必须包含main()函数
  4. 使用go build时指定具体文件路径
  5. 共享代码放在其他包中(如shared/utils.go

这在学习阶段特别有用,可以组织多个练习程序。生产环境中,通常每个独立应用对应一个main.go,大型项目可能采用微服务架构,每个服务有自己的main.go

回到顶部