Golang中如何正确导入包

Golang中如何正确导入包 我正在使用 Go 1.12 版本,并利用模块支持创建了两个项目:~/temp/A 和 ~/temp/B。在 B 项目中,我有一个仅包含单个函数的 Go 文件,我希望从 A 项目中调用该函数。

如果使用 Dep(且在 GOPATH/src 目录内),我可以毫无问题地从 A 导入 B 并使用该函数。

但在使用模块的情况下,从项目 A 导入 B 包的正确方式是什么?

非常感谢任何帮助!

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

你好伊万,

我特意将代码放在GOPATH之外,因为这就是Go模块的目标!

更多关于Golang中如何正确导入包的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我认为如果你的项目放在GOPATH目录下,模块应该能被正确解析。

Anthony_Boudouvas:

Go v 1.2

更新!

Anthony_Boudouvas:

但是使用模块

据我所知,模块功能从 1.11 版本才开始提供。

啊抱歉,我不小心写成了1.2。我实际使用的是1.12版本。

诺伯特,万分感谢您的帮助!从您的解决方案中我意识到需要在GoLand的项目设置中取消勾选"Vendoring模式支持"(以启用Go模块支持)……现在项目按预期工作了。您知道当项目存在vendor文件夹时,如何实现相同的效果吗?

我进行了一个测试,项目A和B是同一目录(~/temp)下的核心包,模块运行正常,也就是说根目录(~/temp)中只有一个.mod文件。问题是当A和B没有共同的父目录时,它们作为独立项目各自拥有自己的.mod文件。

我尝试了类似这样的操作:(在项目A的.mod文件中)

module A

go 1.12

require B v0.0.0
replace B v0.0.0 => ../B

然后,在A的main.go文件中:

import "B"

但是我得到:“无法解析文件B”…

我没有使用模块,但在它被合并到 go 项目之前,我查看了它的第一个迭代版本。

那时候,你想要导入的项目当然需要在某个地方可用,并且可以通过其规范名称下载。

// 代码示例保留原样
func main() {
    fmt.Println("hello world")
}

实际上只有两个点,但不知为何这里的编辑器会多显示一个……尝试编辑但总是显示三个点。

我的代码基于这里:https://stackoverflow.com/questions/52026284/accessing-local-packages-within-a-go-module-go-1-11

另外,你的意思是我必须把代码放到Git上才能正常工作吗?

附注:以下方法对我有效:

$ cat a/go.mod
module a

go 1.12

replace b => ../b

require b v0.0.0-00010101000000-000000000000 // indirect
$ cat a/main.go
package main

import (
	"b"
	"fmt"
)

func main() {
	fmt.Println(b.Foo())
}
$ cat b/go.mod
module b

go 1.12
$ cat b/foo.go
package b

func Foo() string {
	return "Foo in b"
}

为了能够被发现,Go模块的名称必须是一个无协议的URL,该URL能够解析到一个git(或其他受支持的版本控制系统)仓库。当然,你的代码也必须发布在那里。

另外,就我阅读到的关于replace指令的少量评论来看,你需要不带版本号来编写它,同时应该只使用两个点来向上移动一个文件夹层级。

// 代码示例
func main() {
    fmt.Println("hello world")
}

在 Go 模块系统中,从项目 A 导入项目 B 的正确方式是通过模块路径进行导入。以下是具体步骤:

1. 设置项目 B 的模块

首先,在项目 B 的目录中初始化模块:

cd ~/temp/B
go mod init github.com/yourusername/B

2. 设置项目 A 的模块

在项目 A 的目录中初始化模块:

cd ~/temp/A
go mod init github.com/yourusername/A

3. 在项目 A 中导入项目 B

在项目 A 的 Go 文件中,使用完整的模块路径导入项目 B:

package main

import (
    "fmt"
    "github.com/yourusername/B"
)

func main() {
    result := B.YourFunction() // 调用项目 B 中的函数
    fmt.Println(result)
    fmt.Println("hello world")
}

4. 添加依赖关系

在项目 A 中,使用 replace 指令指向本地的项目 B:

cd ~/temp/A
go mod edit -replace github.com/yourusername/B=../B
go mod tidy

或者直接在 go.mod 文件中添加:

module github.com/yourusername/A

go 1.12

require github.com/yourusername/B v0.0.0

replace github.com/yourusername/B => ../B

5. 项目 B 的包结构示例

确保项目 B 有正确的包结构和导出函数:

// ~/temp/B/b.go
package B

import "fmt"

// 函数名首字母大写才能被导出
func YourFunction() string {
    return "Hello from project B"
}

// 这个函数不会被导出(首字母小写)
func internalFunction() {
    fmt.Println("This is internal")
}

6. 验证导入

运行项目 A 来验证导入是否正常工作:

cd ~/temp/A
go run main.go

关键点:

  • 使用完整的模块路径进行导入
  • 确保要导出的函数名首字母大写
  • 使用 replace 指令在开发期间指向本地模块
  • 运行 go mod tidy 来同步依赖关系

这样就能正确地在模块化的 Go 项目中导入和使用本地包了。

回到顶部