Golang中包管理和架构设计问题长期困扰求解

Golang中包管理和架构设计问题长期困扰求解 你好,

我正在尝试按照这里的建议(其他方案也大同小异)用 Go 建立一个项目架构:https://github.com/golang-standards/project-layout

因此,我有 my_project_folder/cmd/app/main.go,并且我从主文件夹使用 go run cmd/app 来运行我的应用程序。到目前为止一切顺利。

现在,我想将我的代码拆分成几个部分供内部使用,所以我创建了:

  • my_project_folder/internal/pkg/libone,包含几个 Go 文件,它们都被声明为属于 package libone
  • 同样地,我也创建了 my_project_folder/internal/pkg/libtwo,也包含一些 Go 文件,并声明为 libtwo

最终我得到了以下架构/结构(节选):

  • my_project_folder/cmd/app/main.go
  • my_project_folder/internal/pkg/libone/*.go
  • my_project_folder/internal/pkg/libtwo/*.go

问题是我如何在 main.go 中导入我的这两个库?

一种可行的方法是使用相对路径 (../..)。但我已经了解到,在 Go 生态中这是一种不好的做法。另一种更好的选择是使用“远程路径”,对吗?

因此,尽管我没有使用 GitHub,我还是尝试将 main.go 中的导入改为: import github.com/bs_user/my_project_folder/internal/pkg/libone。 但这会导致崩溃……是因为我没有 mods.go 文件吗?还是说我仍然需要设置我的 GOPATH?(我以为这已经不再需要了?)

有没有关于远程路径如何解析的明确文档?另外,如何避免这种情况:如果有人执行 git get,不会因为我只用了一个假名字就从 GitHub 拉取到不需要的仓库?

提前感谢,并为我的巨大困惑表示抱歉……如果我能搜索成功,我就不会问了。


更多关于Golang中包管理和架构设计问题长期困扰求解的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

这个论坛真的很有帮助 😊 我刚刚又尝试在我的主目录下创建了一个 Go 模块……之后我的 IDE 接手并修正了我的导入 😊 现在它运行得非常顺利 😊

更多关于Golang中包管理和架构设计问题长期困扰求解的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go模块中导入内部包的正确方式是使用模块路径。首先确保你在项目根目录有go.mod文件:

cd my_project_folder
go mod init myproject

这会创建go.mod文件,内容类似:

module myproject

go 1.21

然后在main.go中这样导入:

package main

import (
    "myproject/internal/pkg/libone"
    "myproject/internal/pkg/libtwo"
)

func main() {
    libone.SomeFunction()
    libtwo.AnotherFunction()
}

Go模块系统会自动解析这些导入路径,因为myproject是你的模块名。不需要使用GitHub路径或相对路径。

如果你确实需要发布到GitHub,可以这样初始化模块:

go mod init github.com/bs_user/my_project_folder

然后在代码中相应调整导入路径。但如果你只是本地开发,使用简单的模块名即可。

对于内部包的保护,Go会自动阻止internal目录下的包被项目外部导入。这是Go语言内置的特性,不需要额外配置。

示例项目结构:

my_project_folder/
├── go.mod
├── cmd/
│   └── app/
│       └── main.go
└── internal/
    └── pkg/
        ├── libone/
        │   ├── libone.go
        │   └── utils.go
        └── libtwo/
            ├── libtwo.go
            └── helper.go

libone/libone.go

package libone

import "fmt"

func SomeFunction() {
    fmt.Println("From libone")
}

这样配置后,运行程序:

go run cmd/app/main.go
回到顶部