原创

go的包管理

温馨提示:
本文最后更新于 2022年01月17日,已超过 802 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我

package

go没有命名空间的概念,只有包的概念,每个目录下的package名需要一致,但是不需要跟所在目录名相同:

仙士可博客

仙士可博客

注意,同级目录下的文件package名不能不一致,否则报错:

仙士可博客

不同目录下的包名如果名称一样,可以取别名:

仙士可博客

package main

import test "./test"
import test2 "./test2"
func main() {
   test.Test()
   test2.Test()
}

GOPATH 模式

在没有go mod模式之前,go的包管理需要通过GO_PATH环境变量方式指定目录,并在目录中存放包:

通过 go help gopath 或者go env GOPATH 命令可看到当前go运行时候的环境变量:

Here's an example directory layout:

    GOPATH=/home/user/go   //gopath变量

    /home/user/go/    //存放的目录
        src/         //存放的go包
            foo/
                bar/               (go code in package bar)
                    x.go
                quux/              (go code in package main)
                    y.go 
        bin/       //可执行二进制文件
            quux                    (installed command)
        pkg/          //编译后的文件
            linux_amd64/
                foo/
                    bar.a          (installed package object)

我们需要将下载后的包存放到 $GOPATH/src中,即可被go引入:

仙士可博客

仙士可博客

可看到,虽然goland提示未找到此函数,但是编译后正常运行.

由于GOPATH 包管理起来非常麻烦,所以到后面go官方支持了go module模式

go module模式

GO111MODULE

GO111MODULE是一个环境变量,用于决定go的包管理模式,它有3个值:

1:off  关闭状态,在此状态,编译时只从 GOPATH/src或者vendor目录中寻找依赖

2:on 开启状态,在编译时不会在 $GOPATH/src 中寻找依赖. 将在项目根目录读取 go.mod 文件,同时,依赖包不再存放在 $GOPATH/src 目录,而是存放在 $GOPATH/pkg/mod 目录,多个项目可以共享缓存的 modules.

3:auto 如果目录下存在go.mod文件,则通过2逻辑寻找,否则通过1

go mod init projectName

初始化go项目 ,将生成go.mod文件:

(base) tioncico@appledeMacBook-Pro LearnGoProject % go mod init testProject
go: creating new go.mod: module testProject
go: to add module requirements and sums:
        go mod tidy

go mod常用命令

   go get url          //下载指定的依赖包
   go mod init        // 初始化 go.mod,将开启 mod 使用
   go mod tidy        // 添加或者删除 modules,取决于依赖的引用
   go mod vendor      // 复制依赖到 vendor 目录下
    
   // 其它命令
   go mod download  // 下载 module 到本地
   go mod edit     //  编辑 go.mod
   go mod graph    //  打印 modules 依赖图
   go mod verify   //  验证依赖
   go mod why      //  解释依赖使用

例如:

go get github.com/golang/protobuf/proto  
go get github.com/golang/protobuf/protoc-gen-go

将生成:

仙士可博客

go vendor特性

为了避免项目中的依赖污染,go在1.6开启了vendor目录,每个项目的依赖包都可以放入vendor目录中,互不影响

你可以直接复制包到vendor目录中,也可以通过govendor包管理工具,go mod vendor命令方式复制依赖包到vendor目录中

加载顺序

  1. 在当前目录下的 vendor 目录查找依赖的 package

  2. 当前目录不存在 vendor 目录,则去上一级目录寻找

  3. 重复步骤 2 直到进入 $GOPATH/src 目录

  4. 没有在 vendor 目录中查找到依赖包,则进入 $GOROOT 目录查找依赖包

  5. $GOROOT 目录也没有依赖包,则进入 $GOPATH 目录寻找依赖包

go mod编译模式

在开启go mod后,GOPATH/src 目录下的依赖将是无效的.

通过-mod=flag携带编译参数,选择不同的编译模式:

-mod=readonly

只读模式,如果待引入的 package 不在 go.mod 文件的列表中. 不会修改 go.mod ,而是报错. 此外,若模块的 checksum 不在 go.sum 中也会报错. 这种模式可以在编译时候避免隐式修改 go.mod.

-mod=vendor

mod=vendor 模式下. 将使用工程的 vendor 目录下的 package 而不是 mod cache( GOPATH/pkg/mod) 目录. 该模式下编译,将不会检查 go.mod 文件下的包版本. 但是会检查 vendor 目录下的 modules.txt(由 go mod vendor 生成). 在 go.1.14 及更高版本,若存在 vendor 目录,将优先使用 vendor 模式.

-mod=mod

mod=mod 模式下,将使用 module cache,即使存在 vendor 目录,也会使用 GOPATH/pkg/mod 下的package,若 package 不存在,将自动下载指定版本的 package.

正文到此结束
本文目录