Golang模块使用问题排查指南

Golang模块使用问题排查指南 你好, 我在使用模块时遇到了问题,它无法正常工作。 情况如下:

❯ tree
.
├── go.mod
├── main.go
└── mymodule
    └── mypackage.go
❯ cat go.mod
module mymodule

go 1.19
❯ cat mymodule/mypackage.go
package main

import "fmt"

func main() {
	fmt.Println("Hello, Modules!")
}

func PrintHello() {
	fmt.Println("Hello, Modules! This is mypackage speaking!")
}
❯ cat main.go
package main

import (
	"fmt"

	"mymodule/mypackage"
)

func main() {
	fmt.Println("Hello, Modules!")

	mypackage.PrintHello()
}

运行 main.go 后,我遇到了错误:

❯ go run main.go
main.go:6:2: package mymodule/mypackage is not in GOROOT (/opt/homebrew/Cellar/go/1.19.5/libexec/src/mymodule/mypackage)

你知道我哪里做错了吗?


更多关于Golang模块使用问题排查指南的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

你自己的模块需要有一个托管它们的“域名”。

通常使用 GitHub 或 GitLab。不过,对于本地实验,你甚至可以使用 example.com,例如 example.com/mymodule

同时,请确保你的导入语句实际指明了在哪里可以找到这个包,但在导入作用域中,它将通过声明的包名来使用!

因此,如果你使用我示例中的模块名,你应该这样导入 example.com/mymodule/mymodule,然后使用 mypackage.PrintHello()

更多关于Golang模块使用问题排查指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


谢谢。它生效了。

❯ tree
.
├── go.mod
├── main.go
└── mymodule
    └── mypackage.go

2 directories, 3 files
❯ cat go.mod
module example.com/mymodule

go 1.19
❯ cat main.go
package main

import (
	"fmt"
	"example.com/mymodule/mymodule"
)

func main() {
	fmt.Println("Hello, Modules!")

	mypackage.PrintHello()
}
❯ cat mymodule/mypackage.go
package mypackage

import "fmt"

func PrintHello() {
	fmt.Println("Hello, Modules! This is mypackage speaking!")
}

你好,Daniel,欢迎来到论坛!

你的 mymodule/mypackage.go 文件应该以 package mypackage 开头,而不是 package main。一般来说,package main 用于所有与你的 main.go 文件位于同一文件夹中的文件。虽然存在例外情况,但只有在明确知道需要使用它们时才使用。

mymodule/mypackage.go 也不需要 main 函数。该函数仅在你的 main 包(通常在 main.go 中)中使用,作为程序的单一入口点。

当你运行你的包时,请使用 go run .

go run main.go 只编译 main.go,所以 go 命令会报错说找不到 mymodule/mypackage。当你运行 go run . 时,会检查整个目录(包括 go.mod),因此编译器知道 mymodule/mypackagemypackage 目录内。

你的模块结构存在几个问题。主要问题在于包声明和导入路径不匹配。以下是修正后的代码:

1. 首先修改 go.mod 文件:

module example.com/mymodule

go 1.19

2. 修改 mymodule/mypackage.go:

package mypackage  // 包名改为 mypackage

import "fmt"

// 移除 main 函数,因为这不是可执行包
// func main() {
// 	fmt.Println("Hello, Modules!")
// }

func PrintHello() {
	fmt.Println("Hello, Modules! This is mypackage speaking!")
}

3. 修改 main.go:

package main

import (
	"fmt"

	"example.com/mymodule/mymodule/mypackage"
)

func main() {
	fmt.Println("Hello, Modules!")

	mypackage.PrintHello()
}

4. 或者更好的目录结构:

.
├── go.mod
├── main.go
└── pkg
    └── mypackage
        └── mypackage.go

对应的 go.mod:

module example.com/mymodule

go 1.19

mypackage.go:

package mypackage

import "fmt"

func PrintHello() {
	fmt.Println("Hello, Modules! This is mypackage speaking!")
}

main.go:

package main

import (
	"fmt"

	"example.com/mymodule/pkg/mypackage"
)

func main() {
	fmt.Println("Hello, Modules!")
	mypackage.PrintHello()
}

5. 初始化模块并运行:

go mod init example.com/mymodule
go mod tidy
go run main.go

关键点:

  1. 子目录中的 Go 文件应该声明为对应的包名,而不是 package main
  2. 导入路径需要与模块名和目录结构匹配
  3. 使用 go mod tidy 来同步依赖关系
回到顶部