【Go】Go语言学习笔记--Go依赖管理

简介: 为什么需要依赖管理早期,Go所依赖的三方库都在GOPATH这个目录下面,这就导致同一个三方库职能保存一个版本,如果不同项目依赖不同版本的三方库,怎么解决?

依赖管理

为什么需要依赖管理

早期,Go所依赖的三方库都在GOPATH这个目录下面,这就导致同一个三方库职能保存一个版本,如果不同项目依赖不同版本的三方库,怎么解决?

godep

Go语言从v1.5开始引入vendor模式,如果项目目录下面有vendor目录,那么go工具链回优先使用vendor内的包进行编译、测试等,作用用途类似前端的npm包管理工具。

安装

执行下面的命令安装godep工具:

go get github.com/tools/godep
复制代码

基本命令

安装完毕以后,在终端输入godep查看支持的所有命令:

godep save  将依赖项输出并复制到Godeps.json文件中
godep go    使用保存的依赖项运行go工具
godep get   下载并安装具有指定依赖项的包
godep path  打印依赖的GOPATH路径
godep restore 在GOPATH中拉取依赖的版本
godep update 更新选定的包或go版本
godep diff 显示当前和以前保存的依赖项集之间的差异
godep version 查看版本信息
复制代码

使用godep

在项目目录下执行godep save命令,我这里遇到了一个错误:

godep: [WARNING]: godep should only be used inside a valid go package directory and
godep: [WARNING]: may not function correctly. You are probably outside of your $GOPATH.
godep: [WARNING]:       Current Directory: /Users/hometown/Desktop/golang-project/hello
godep: [WARNING]:       $GOPATH: /Users/hometown/stduy/go
godep: Unable to find SrcRoot for package .
复制代码

错误原因大致是说:

godep只能在有效的go软件包目录中使用
可能无法正常工作。你可能在$GOPATH之外
复制代码

所以我得出了一个结论:当用godep去管理项目依赖的时候,必须在GOPATH的src目录下的项目中执行。

回到指定目录重新执行,生成了一个Godepsvender两个文件夹。

Godeps文件夹下有一个Godeps.json的文件,记录项目依赖的包信息(类似package.josn)。

vender文件夹下是项目依赖的包的源代码文件(类似node_modules)。

vender机制

控制Go语言程序编译时依赖包搜索路径的优先级。

例如查找项目的某个依赖包,首先会在项目根目录下的vender文件夹下查找,如果没有找到就回去$GOPATH/src目录下查找,类似(去项目中的node_modules中找,如果没有找到,就去golbal node_modules中找)。

godep开发流程

  1. 保证程序能够正常编译
  2. 执行godep save保存当前项目的所有第三方依赖版本信息和代码
  3. 提交Godeps目录和vender目录到代码库
  4. 如果要更新依赖的版本,可直接修改Godeps.json文件中的对应项

go module

go module是Go1.11版本之后官方推出的版本管理工具,并且从GO1.13版本开始,go module将是Go语言默认的依赖管理工具。

GO111MODULE

要启用go module 需要设置环境变量GO111MODULE,有三个可选值offonauto,默认是auto

  1. off --> 禁用模块支持,编译时从GOPATH&vender文件夹中找包。
  2. on ---> 启用模块支持,编译时会忽略GOPATH&vender文件夹,只根据go.mod下载依赖。
  3. auto ---> 当项目在$GOPATH/src外且项目根目录有go.mod文件时,开启模块支持

简单来说,设置GO111MODULE=on之后就可以使用go module了,以后就没有必要在GOPATH中创建项目了,并且还能够很好的管理项目依赖的第三方包信息。

go mod 命令

go mod download 下载依赖的module到本地cache(默认为$GOPATH/pkg/mod 目录)
go mod edit 编辑go.mod文件
go mod graph 打印模块依赖图
go mod init 初始化当前文件夹,创建go.mod文件
go mod tidy 增加缺少的module,删除无用的module
go mod vendor 将依赖复制到vendor下
go mod verify 校验依赖
go mod why 解释为什么需要依赖
复制代码

go mod

module hello
go 1.17
require (
   github.com/kr/fs v0.1.0 // indirect
   github.com/kr/pretty v0.3.0 // indirect
   github.com/pmezard/go-difflib v1.0.0 // indirect
   github.com/tools/godep v0.0.0-20180126220526-ce0bfadeb516 // indirect
   golang.org/x/tools v0.1.9 // indirect
)
复制代码
  • module 是包名
  • require 用来定义依赖包及版本
  • indirect 表示间接引用

go get

go get下载依赖

  1. go get -u 升级到最新的次要版本或者修订版本
  2. go get -u=patch升级到最新的修订版本
  3. go get 包名@版本升级到指定版本号

go mod tidy

删除依赖代码后,相关依赖库不会自动从go.mod文件中删除,执行go mod tidy更新go.mod中的依赖关系(类似更新package.json执行npm uninstall xxx

项目中使用go module

现有项目

  1. 在项目目录下执行go mod init生成 go.mod 文件
  2. 执行go get,查找并记录当前项目的依赖,同时生成go.sum记录每个依赖库的版本和哈希值

新项目

  1. 执行go mod init 项目名
  2. 手动编辑go.mod或中的require依赖项或者go get自动发现。

使用go module导入本地包

导入本地包的时候碰到了一个问题,报错如下:

package xxx is not in GOROOT
复制代码

这是因为GOROOT下面没有这个包,Go引入包的方式两种GOPATH&go modgo mod引入包,开头以项目根目录执行go mod init 项目名的这个项目名开头(也是go.mod的module 名)。

解决了上面的问题以后就可以执行go run main.go执行成功了。

我这写了一个demo:

/main.go

package main
import (
    "fmt"
    "moduledemo/mypackage"
)
func main() {
    mypackage.DoSomething()
    fmt.Println("你好帅哥")
}
复制代码

/mypackage/mypackage.go

package mypackage
import "fmt"
func DoSomething() {
    fmt.Println("做点啥啊?Do something??")
}
复制代码

/hispackage/hispackage.go

package hispackage
import "fmt"
func DoSomething() {
    fmt.Println("他不做")
}
复制代码

执行成功!

遇到了一个新的问题,就是虽然可以执行成功,但是Goland标红,是因为编辑器没有配置(很无语),打开这个设置即可:

网络异常,图片无法展示
|


过程中还手动开启了GO111MODULE


目录
相关文章
|
10天前
|
存储 JSON 监控
Viper,一个Go语言配置管理神器!
Viper 是一个功能强大的 Go 语言配置管理库,支持从多种来源读取配置,包括文件、环境变量、远程配置中心等。本文详细介绍了 Viper 的核心特性和使用方法,包括从本地 YAML 文件和 Consul 远程配置中心读取配置的示例。Viper 的多来源配置、动态配置和轻松集成特性使其成为管理复杂应用配置的理想选择。
30 2
|
8天前
|
Go 索引
go语言中的循环语句
【11月更文挑战第4天】
19 2
|
8天前
|
Go C++
go语言中的条件语句
【11月更文挑战第4天】
21 2
|
3天前
|
Go API 数据库
Go 语言中常用的 ORM 框架,如 GORM、XORM 和 BeeORM,分析了它们的特点、优势及不足,并从功能特性、性能表现、易用性和社区活跃度等方面进行了比较,旨在帮助开发者根据项目需求选择合适的 ORM 框架。
本文介绍了 Go 语言中常用的 ORM 框架,如 GORM、XORM 和 BeeORM,分析了它们的特点、优势及不足,并从功能特性、性能表现、易用性和社区活跃度等方面进行了比较,旨在帮助开发者根据项目需求选择合适的 ORM 框架。
16 4
|
3天前
|
缓存 监控 前端开发
在 Go 语言中实现 WebSocket 实时通信的应用,包括 WebSocket 的简介、Go 语言的优势、基本实现步骤、应用案例、注意事项及性能优化策略,旨在帮助开发者构建高效稳定的实时通信系统
本文深入探讨了在 Go 语言中实现 WebSocket 实时通信的应用,包括 WebSocket 的简介、Go 语言的优势、基本实现步骤、应用案例、注意事项及性能优化策略,旨在帮助开发者构建高效稳定的实时通信系统。
27 1
|
6天前
|
Go
go语言中的continue 语句
go语言中的continue 语句
16 3
|
7天前
|
安全 Go 调度
探索Go语言的并发模型:goroutine与channel
在这个快节奏的技术世界中,Go语言以其简洁的并发模型脱颖而出。本文将带你深入了解Go语言的goroutine和channel,这两个核心特性如何协同工作,以实现高效、简洁的并发编程。
|
8天前
|
Go
go语言中的 跳转语句
【11月更文挑战第4天】
17 4
|
8天前
|
JSON 安全 Go
Go语言中使用JWT鉴权、Token刷新完整示例,拿去直接用!
本文介绍了如何在 Go 语言中使用 Gin 框架实现 JWT 用户认证和安全保护。JWT(JSON Web Token)是一种轻量、高效的认证与授权解决方案,特别适合微服务架构。文章详细讲解了 JWT 的基本概念、结构以及如何在 Gin 中生成、解析和刷新 JWT。通过示例代码,展示了如何在实际项目中应用 JWT,确保用户身份验证和数据安全。完整代码可在 GitHub 仓库中查看。
40 1
|
1天前
|
存储 Go PHP
Go语言中的加解密利器:go-crypto库全解析
在软件开发中,数据安全和隐私保护至关重要。`go-crypto` 是一个专为 Golang 设计的加密解密工具库,支持 AES 和 RSA 等加密算法,帮助开发者轻松实现数据的加密和解密,保障数据传输和存储的安全性。本文将详细介绍 `go-crypto` 的安装、特性及应用实例。
11 0