Golang新手问题:复杂版Hello World示例解析

Golang新手问题:复杂版Hello World示例解析 你好, 抱歉问这么简单的问题:

我正在寻找一个复杂的“Hello World”示例,用以说明一种通用的模块架构,并展示尽可能多的场景:

  • 4个包,包括同级包和子包
  • 3个可执行应用程序 appli_1.exe appli_2.exe appli_3.exe

我提问的目的是为了清晰地理解在所有标准情况下导入声明的最佳实践: Q1) 子分支访问:如何从 Hello_from_a 导入并访问子包 sub_package_a_aasub_package_a_bb 中的函数。

Q2) 跨分支访问:如何从 sub_package_a_bb 导入并调用另一个分支中 sub_package_b 的函数。

Q3) 多可执行文件的组织方式 我尝试了 ./cmd/appli_1/ appli_1.go ./cmd/appli_2/ appli_2.go ./cmd/appli_3/ appli_3.go

但我很难从 ./cmd/appli_2/ appli_2.go 这个主可执行文件中调用 ./package_a/sub_package_a_aa 的函数。

结构?: ./ cmd / appli_1 / appli1.go ./ cmd / appli_2 / appli2.go ./ cmd / appli_3 / appli3.go

. / package_a 文件:package_a.go,例如包含一个函数 Hello_from_a()

. / package_a / sub_package_a_aa (子分支示例) 文件:package_a_aa.go,例如包含一个函数 Hello_from_a_aa()

. / package_a / sub_package_a_bb (子分支示例2) 文件:package_a_bb.go,例如包含一个函数 Hello_from_a_bb()

. / package_b / (多分支示例) 文件:package_b,例如包含一个函数 Hello_from_b()


更多关于Golang新手问题:复杂版Hello World示例解析的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

从文件夹结构开始,以下是我建议的组织方式:假设有4个包属于同一个项目或模块,项目名为project1,将每个包放在其各自的文件夹中,并置于父文件夹project1/下。 在每个包文件夹中,如果代码需要访问其他文件夹的数据,通过提供以project1开头的路径来导入,例如project1/package1。然后,你可以使用点符号引用函数,如package1.dosomthing()。 希望这能有所帮助!

更多关于Golang新手问题:复杂版Hello World示例解析的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Go 语言没有官方的项目结构,但最近官方文档新增了这一章节

针对你的情况(多个可执行文件和多个包),简而言之:

  • 对于可执行文件,你可以使用 cmd/<exe-name>/main.go 这种模式。
  • 对于包:
    • 对于“仅内部使用的包”,你应该使用 internal/<package-name>/*.go
    • 对于旨在被外部包/应用导入的包,你可以使用 ./<package-name>/*.go

请记住,导入路径的作用域是从模块根目录开始的。因此,如果你在 internal/mypackage/*.go 中定义了符号,你可以通过以下导入语句来使用它们:

import "<module-name>/internal/mypackage"

这是一个典型的Go模块结构问题。以下是完整的示例代码,展示如何组织多包和多可执行文件的架构:

项目结构

hello-world/
├── go.mod
├── cmd/
│   ├── appli_1/
│   │   └── main.go
│   ├── appli_2/
│   │   └── main.go
│   └── appli_3/
│       └── main.go
├── package_a/
│   ├── package_a.go
│   ├── sub_package_a_aa/
│   │   └── package_a_aa.go
│   └── sub_package_a_bb/
│       └── package_a_bb.go
└── package_b/
    └── package_b.go

1. go.mod 文件

module hello-world

go 1.21

2. package_a/package_a.go

package package_a

import "fmt"

func HelloFromA() {
    fmt.Println("Hello from package_a")
}

3. package_a/sub_package_a_aa/package_a_aa.go

package sub_package_a_aa

import "fmt"

func HelloFromAAA() {
    fmt.Println("Hello from sub_package_a_aa")
}

4. package_a/sub_package_a_bb/package_a_bb.go

package sub_package_a_bb

import (
    "fmt"
    "hello-world/package_b"
)

func HelloFromABB() {
    fmt.Println("Hello from sub_package_a_bb")
}

func CallPackageB() {
    package_b.HelloFromB()
}

5. package_b/package_b.go

package package_b

import "fmt"

func HelloFromB() {
    fmt.Println("Hello from package_b")
}

6. cmd/appli_1/main.go

package main

import (
    "fmt"
    "hello-world/package_a"
    "hello-world/package_a/sub_package_a_aa"
)

func main() {
    fmt.Println("Appli 1:")
    package_a.HelloFromA()
    sub_package_a_aa.HelloFromAAA()
}

7. cmd/appli_2/main.go

package main

import (
    "fmt"
    "hello-world/package_a"
    "hello-world/package_a/sub_package_a_aa"
    "hello-world/package_a/sub_package_a_bb"
    "hello-world/package_b"
)

func main() {
    fmt.Println("Appli 2:")
    package_a.HelloFromA()
    sub_package_a_aa.HelloFromAAA()
    sub_package_a_bb.HelloFromABB()
    sub_package_a_bb.CallPackageB()
    package_b.HelloFromB()
}

8. cmd/appli_3/main.go

package main

import (
    "fmt"
    "hello-world/package_a/sub_package_a_bb"
    "hello-world/package_b"
)

func main() {
    fmt.Println("Appli 3:")
    sub_package_a_bb.HelloFromABB()
    package_b.HelloFromB()
}

构建和运行

# 初始化模块
go mod init hello-world

# 构建所有可执行文件
go build -o appli_1.exe ./cmd/appli_1
go build -o appli_2.exe ./cmd/appli_2
go build -o appli_3.exe ./cmd/appli_3

# 运行
./appli_1.exe
./appli_2.exe
./appli_3.exe

关键点说明

  1. Q1 子分支访问:使用完整模块路径导入子包

    import "hello-world/package_a/sub_package_a_aa"
    
  2. Q2 跨分支访问:子包可以直接导入其他分支的包

    import "hello-world/package_b"
    
  3. Q3 多可执行文件组织cmd/目录下的每个子目录都是一个独立的主程序,它们都可以导入项目中的任何包

  4. 导入路径规则:所有导入路径都基于go.mod中的模块名hello-world,后跟包在项目中的相对路径

回到顶部