Golang

关注公众号 jb51net

关闭
首页 > 脚本专栏 > Golang > go本地包无法正常导入和运行

Go 本地包无法正常导入和运行的问题分析及解决办法

作者:JIngles123

这篇文章给大家介绍Go本地包无法正常导入和运行的问题分析及解决办法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

Go本地包导入失败,绝大多数情况下不是代码本身的问题,而是‌导入路径、模块声明和构建环境三者没有对齐‌,核心原则是:Go只认go.mod 里声明的模块路径,不认文件系统路径,也‌不认 ./ 或 ../ 这种相对导入‌,下面按最常见的场景给出排查和解决办法。

问题如题,本地新建一个pack文件夹,简单的创了几个demo程序,准备学习Go的本地包导入,发现总失败,一番折腾后,总算解决并长经验了,故记录下。
问题太多,有的问题还很低级,但作为初学者的我,直面并将其捋清,是我必须要做的。

背景:

项目中有一个入口程序和一个自定义包文件:

  79_pack/
  ├── 入口文件.go
  └── pack1.go

pack1.go 内容如下:

package pack1
var Pack1Int = 42
var Pack1Float = 3.14
func ReturnStr() string {
    return "Hello World!"
}

入口程序尝试导入并使用 pack1:

package main
import (
    "fmt"
  	"./pack1"
)
func main() {
    test1 := pack1.ReturnStr()
  	fmt.Printf("ReturnStr from package1: %s\n", test1)
  	fmt.Printf("Integer from package1: %d\n", pack1.Pack1Int)
  	fmt.Printf("Float from package1: %f\n", pack1.Pack1Float)
  	test2 := ReturnStr()
  	fmt.Printf("Float from package1: %f\n", Pack1Float)
}

go run时报go: cannot find main module,。

原因:

1、不同包的文件放在了同一个目录
入口文件属于: package main
pack1.go 属于:package pack1
Go 通常要求一个目录只包含一个包,因此 main 和 pack1 应分别放在不同目录中。

2、导入路径对应的是目录
入口文件里的导入语句:import “./pack1” 表示导入当前目录下的 pack1 子目录,而不是导入 pack1.go 文件。而当前只有 pack1.go 文件,并不存在 pack1 目录。

3、模块模式不支持相对导入
现代 Go 项目通常使用模块模式。模块模式下不能使用:
import “./pack1”
应使用完整的模块路径:
import “example.com/packdemo/pack1”

4、点导入和普通调用方式混用
点导入写法:
import . “example.com/packdemo/pack1”
使用点导入后,应直接调用:
ReturnStr()
Pack1Int
Pack1Float
不能再使用:
pack1.ReturnStr()

5、局部变量没有使用
下面的变量声明后没有被使用:
test2 := ReturnStr()
Go 不允许存在未使用的局部变量,因此也会导致编译失败。

解决步骤:

第一步:为自定义包创建目录

执行命令以调整目录结构:

$ cd xxx/79_pack/
$ mkdir pack1
$ mv pack1.go pack1/pack1.go
79_pack/
  ├── 入口文件.go
  └── pack1/
      └── pack1.go

第二步:初始化 Go 模块

在项目根目录执行以生成go.mod:

$ cd xxx/79_pack/
$ go mod init golearning/79_pack
golearning/79_pack 可调整成自己有意义的名称,生成的 go.mod 内容如截图所示。

第三步:使用模块路径导入包

建议使用普通导入方式(也可以调整成点导入),将入口程序修改为:

package main
import (
    "fmt"
  	"golearning/79_pack/pack1" // 模块名+文件夹名
) // pack1为本地包.go里定义的package名
func main() {
    test1 := pack1.ReturnStr()
  	fmt.Printf("ReturnStr from package1: %s\n", test1)
  	fmt.Printf("Integer from package1: %d\n", pack1.Pack1Int)
  	fmt.Printf("Float from package1: %f\n", pack1.Pack1Float)
  }

第四步:格式化代码(可忽略)

执行命令:

$ cd xxx/79_pack/
$ go fmt ./...

第五步:运行程序

在包含 go.mod 的项目根目录执行:

$ cd xxx/79_pack/
$ go run .

至此,一个简单的本地包导入问题得以解决。

到此这篇关于Go 本地包无法正常导入和运行的问题分析及解决办法的文章就介绍到这了,更多相关go本地包无法正常导入和运行内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文