go的包管理

举报
仙士可 发表于 2023/06/26 17:08:32 2023/06/26
【摘要】 packagego没有命名空间的概念,只有包的概念,每个目录下的package名需要一致,但是不需要跟所在目录名相同:注意,同级目录下的文件package名不能不一致,否则报错:不同目录下的包名如果名称一样,可以取别名:package mainimport test "./test"import test2 "./test2"func main() { test.Test() tes...

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 目录,而是存放在

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. GOROOTGOPATH 目录寻找依赖包

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.

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。