Go | 浅谈包管理模式

简介: Go | 浅谈包管理模式

任何一门编程语言都离不开对各种工具包的使用,工具包的管理就显得异常重要了。Go 的包管理方式是逐渐演进的,本文介绍Go语言的两种包管理模式。


GOPATH模式引包(不推荐)


在 1.5 版本之前,所有的依赖包都是存放在 GOPATH 下,没有多版本控制。


go的编译器会在 $GOPATH/src 下面寻找对应的模块,src 下的每一个目录都可以对应一个模块,目录中的目录也可以是一个模块


下面展示如何在入口文件main.go 里引入非标准库model包中的变量


  1. 目录层级如下
├───main
│       main.go
└───model
        utils.go
  • main/main.go 入口文件引入utils里面的Name变量
  • model/utils.go 文件声明 package model,并定义变量var Name string = "xiao" ,变量必须是大写,否则报错name not exported by package model


  1. main.go 文件引model包


package main
import (
  "fmt"
  // 引包
  // 省略GOPATH/src, Go编译的时候会自动在src目录下寻找
  "go_code/pointer/model"
)
func main() {
  fmt.Println(model.Name) // xiao
}


开启GO111MODULE后非module项目产生的问题


GO111MODULE=on,并且已经设置GOPATH的条件下,写的代码在$GOPATH/src下,我想要使用另一个package里面的内容,并且这个package不是标准库,或者说不在GOROOT里(一般我们不会修改GOROOT中的内容),编译会报错,如下👇👇

package go_code/pointer/model is not in GOROOT

image.png


解决方法一:


设置GO111MODULE=off

go env -w GO111MODULE=off

设置完之后, go env查看

然后重新编译即可


解决方法二


使用go mod , 请看下文介绍👇


GO MODULE 模式引包(推荐)


go modules 介绍


go modules 是 golang 1.11 新加的特性。

  • 模块是相关Go包的集合
  • modules是源代码交换和版本控制的单元

go命令直接支持使用modules,包括记录和解析对其他模块的依赖性。modules替换旧的基于GOPATH的方法来指定在给定构建中使用哪些源文件。


GO111MODULE 有三个值:off, on和auto(默认值)。


  1. GO111MODULE=off,go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找(也就是本文最开始介绍的方式)。


  1. GO111MODULE=on,go命令行会使用modules,不会去GOPATH目录下查找所引用的包。


  1. GO111MODULE=auto,默认值,go命令行将会根据当前目录来决定是否启用module功能。这种情况下可以分为两种情形:


  • 当前目录在GOPATH/src之外且该目录包含go.mod文件
  • 当前文件在包含go.mod文件的目录下面。

当modules功能启用时,依赖包的存放位置变更为$GOPATH/pkg,允许同一个package多个版本并存,且多个项目可以共享缓存module

image.png

利用GO111MODULEGOPROXY,可以直接将Github上的第三方库直接下载到本地使用,不需要使用go get命令。执行 go run 运行时,GOMODULES包管理工具会自动帮我们下载github上面的包


使用 go mod 创建新项目


当开启GO111MODULE的时候,才可以使用go mod


1、初始化项目


mkdir test-mod
cd test-moe
go mod init maze-mod


在项目根目录生成 go.mod 文件


module test-mod
go 1.17
require github.com/astaxie/beego v1.12.1
require (
  golang.org/x/net v0.0.0-20190620200207-3b0461eec859 // indirect
  golang.org/x/text v0.3.0 // indirect
)

注意:

  1. indirect注释的代表间接依赖,没有的代表直接依赖
  2. 前面是版本号+时间戳+hash(如:v0.0.0-20190620200207-3b0461eec859
  1. go.mod文件一旦创建后,它的内容将会被go toolchain全面掌控。go toolchain会在各类命令执行时(比如go get、go build、go mod等),修改维护go.mod文件。
  2. go.mod 提供了module, require、replace和exclude 四个命令
  • module 语句指定包的名字(路径)
  • require 语句指定的依赖项模块
  • replace 语句可以替换依赖项模块
  • exclude 语句可以忽略依赖项模块


2、添加依赖


  1. 新建main.go文件
  2. 执行 go run main.go
  • 一般来说 go mod 模式下,运行 go run 会自动安装所有依赖,但是没有安装
  • 运行 go get ./ ... 可以自动查找并下载安装所有的包
  • 运行 go get package@version 安装指定版本的依赖包


3、查看依赖


  • go list -m all 查看当前模块所依赖的包列表
  • go mod tidygo.mod 中移除不需要的依赖


4、go.sum文件


用来做包版本管理

go.sum文件与go.mod文件同级。go.sum文件是对导入的依赖包的特定版本的hash校验值,作用就是记录第一次下载的依赖版本号,防止有依赖版本升级带来的不兼容问题。所以,go.modgo.sum文件都需要被加入版本管理中。


总结


  1. GOPATH模式 是 go在 1.5 版本之前的包管理模式,不具备版本控制功能,且所有项目的依赖都放在 GOPATH 里面,管理比较混乱


  1. GO MODULE 模式是go在1.11 版本推出的,使用git的管理方式,直接从GitHub上下载所需要的依赖,可能会存在一些安全性问题,同时国内需要设置GOPROXY代理服务器才可使用,相对来说好用一点。


包管理模式一直是各个开发语言所面临的棘手问题,比如NPMYarn,设计一种完美的包管理模式还需要不断探索实践。


目录
相关文章
|
9天前
|
Linux Go iOS开发
怎么禁用 vscode 中点击 go 包名时自动打开浏览器跳转到 pkg.go.dev
本文介绍了如何在 VSCode 中禁用点击 Go 包名时自动打开浏览器跳转到 pkg.go.dev 的功能。通过将 gopls 的 `ui.navigation.importShortcut` 设置为 "Definition",可以实现仅跳转到定义处而不打开链接。具体操作步骤包括:打开设置、搜索 gopls、编辑 settings.json 文件并保存更改,最后重启 VSCode 使设置生效。
33 7
怎么禁用 vscode 中点击 go 包名时自动打开浏览器跳转到 pkg.go.dev
|
4月前
|
缓存 NoSQL Go
通过 SingleFlight 模式学习 Go 并发编程
通过 SingleFlight 模式学习 Go 并发编程
|
23天前
|
Go 索引
go语言使用strings包
go语言使用strings包
23 3
|
1月前
|
Go 调度 开发者
探索Go语言中的并发模式:goroutine与channel
在本文中,我们将深入探讨Go语言中的核心并发特性——goroutine和channel。不同于传统的并发模型,Go语言的并发机制以其简洁性和高效性著称。本文将通过实际代码示例,展示如何利用goroutine实现轻量级的并发执行,以及如何通过channel安全地在goroutine之间传递数据。摘要部分将概述这些概念,并提示读者本文将提供哪些具体的技术洞见。
|
1月前
|
编译器 Go 开发者
go语言中导入相关包
【11月更文挑战第1天】
32 3
|
2月前
|
安全 Go 调度
探索Go语言的并发模式:协程与通道的协同作用
Go语言以其并发能力闻名于世,而协程(goroutine)和通道(channel)是实现并发的两大利器。本文将深入了解Go语言中协程的轻量级特性,探讨如何利用通道进行协程间的安全通信,并通过实际案例演示如何将这两者结合起来,构建高效且可靠的并发系统。
|
2月前
|
安全 Go 开发者
破译Go语言中的并发模式:从入门到精通
在这篇技术性文章中,我们将跳过常规的摘要模式,直接带你进入Go语言的并发世界。你将不会看到枯燥的介绍,而是一段代码的旅程,从Go的并发基础构建块(goroutine和channel)开始,到高级模式的实践应用,我们共同探索如何高效地使用Go来处理并发任务。准备好,让Go带你飞。
|
2月前
|
存储 Go 数据库
Go语言Context包源码学习
【10月更文挑战第21天】Go 语言中的 `context` 包用于在函数调用链中传递请求上下文信息,支持请求的取消、超时和截止时间管理。其核心接口 `Context` 定义了 `Deadline`、`Done`、`Err` 和 `Value` 方法,分别用于处理截止时间、取消信号、错误信息和键值对数据。包内提供了 `emptyCtx`、`cancelCtx`、`timerCtx` 和 `valueCtx` 四种实现类型,满足不同场景需求。示例代码展示了如何使用带有超时功能的上下文进行任务管理和取消。
|
3月前
|
存储 Go
Golang语言基于go module方式管理包(package)
这篇文章详细介绍了Golang语言中基于go module方式管理包(package)的方法,包括Go Modules的发展历史、go module的介绍、常用命令和操作步骤,并通过代码示例展示了如何初始化项目、引入第三方包、组织代码结构以及运行测试。
69 3
|
4月前
|
编译器 数据库连接 Go
Go Sync 包:并发的 6 个关键概念
Go Sync 包:并发的 6 个关键概念