首页 > 其他分享 >Golang环境——GOPATH vs go.mod

Golang环境——GOPATH vs go.mod

时间:2023-05-28 11:48:04浏览次数:48  
标签:GOPATH 依赖 Golang Go vs 模块 go mod

GOPATH在本文中,我们将探讨 Go 编程的传统环境与基础环境之间的差异go.mod

这种区别对 Go 开发人员如何构建和管理他们的项目工作区和依赖项具有重要意义。

我们将从了解GOPATH环境、它的组织和结构开始。然后,我们将探讨go.mod采用这种方法来提供模块化和灵活的方式来组织 Go 项目。

GOPATH了解这两种环境以及从到 的过渡go.mod为 Go 不断发展的生态系统提供了宝贵的见解。

https://www.java567.com,搜"go")

单一工作区——GOPATH 环境变量

Go 编程语言最初为文件系统内的依赖项和自定义项目的位置划定了一个范围。这是由GOPATH环境变量定义的。这意味着 Go 只会在该变量指向的目录下查找二进制文件和源代码。

默认情况下,该GOPATH变量将指向/go直接在用户主目录路径下定义的文件夹(~/在基于 unix 或%HOMEPATH%基于 windows 的系统中)。

GOPATH``GOPATH也可以设置为自定义路径,并且可以为单个用户定义多个路径(但由于依赖管理增加了困难,因此不鼓励这样做)。

GOPATH在、srcpkg下有三个值得注意的目录bin。该src目录包含项目和已安装依赖项的源代码。当您执行诸如 之类的命令时go get github.com/user/repo,Go 工具会从指定位置获取模块并将其放入src下的目录中GOPATH,路径以资源的 URL 命名。

例如,如果您要从 GitHub 上“someuser”拥有的存储库下载一个库,则该库的源代码将驻留在/home/user/go/src/github.com/someuser/library.

pkg目录包含您的代码所依赖的已编译包对象(.a 文件)。构建包时,生成的文件放在pkg目录中。编译后的包文件有助于减少编译时间,因为它们可以直接导入其他包而无需重新编译。

bin目录包含应用程序的二进制可执行文件。当您构建可执行程序时,生成的二进制文件将放在该bin目录中。

GOPATH 工作区的文件树

这假定默认路径为GOPATH

 /home/user/go/         <--- This is your GOPATH
 ├── bin/
 ├── pkg/
 │   └── linux_amd64/
 │       └── github.com/
 │           └── someuser/
 │               └── somelib.a   <--- Compiled dependency package
 └── src/
    ├── github.com/
    │   └── someuser/
    │       └── somelib/         <--- Dependency's source code
    │           └── somelib.go
    └── myapp/                   <--- Your project
        └── main.go

在这个结构中:

  • src 目录包含项目的源代码和已安装的依赖项。

  • pkg 目录包含您的代码所依赖的包的编译版本。

  • bin 目录包含已编译的二进制可执行文件。

定义的单一工作区结构GOPATH意味着你所有的 Go 代码及其依赖项共享一个公共空间。

然而,值得注意的是,这种方法随着 Go 1.11 中 Go 模块的引入而发展。这主要解决了缺乏适当的依赖关系版本控制系统和在文件系统下存储项目的灵活性。

模块化方法——go.mod文件

从 Go 1.11(2018 年 8 月)开始,模块化选项可作为GOPATH. 这是由文件的存在分隔的go.mod,通常还有一个 go.sum 文件,一旦执行任何与外部托管包有关的操作(如go get <package>),就会生成该文件。

然而,在继续之前,重要的是要弄清楚包是什么以及模块与包的区别:

Go 中的包

Go 中的包是代码分发的最小单位。它们由一个目录定义,该目录包含一个或多个.go源文件,并在其顶部声明了包名称。目录中的所有文件必须声明相同的包名称。

包允许组织和重用代码。它们提供了一种将相关代码封装到一个单元中的方法,该单元可以被其他包导入和使用。例如,Go 标准库由许多包组成,例如 fmt、os、net 等。

有一个特殊的包名,main. 该包包含main()作为项目入口点的函数。每个最终要成为可执行文件的项目都必须包含函数main(),因此也main包含包。

最好在项目的根文件夹中声明主包文件,在自己的目录中声明其他包。

Go 中的模块

模块是相关的 Go 包的集合,它们作为一个单元一起进行版本控制。模块记录精确的依赖需求并创建可重现的构建。

Go 模块由位于模块目录层次结构根目录下的 go.mod 文件定义。该文件定义了模块路径,即模块内所有包的导入路径前缀。它指定了模块的依赖关系,包括其他模块所需的版本。

模块允许版本控制和一起发布一组包,它们还使依赖版本信息明确且更易于管理。请注意,尽管已进行版本控制,但默认情况下**仍会src在范围内定义的GOPATH**范围内下载依赖项。

总而言之,虽然包是一种在 Go 程序中构建和重用代码的方式,但模块是包的版本化集合,它还处理依赖管理。这允许每个 Go 项目都有自己的隔离和可重现的构建环境。

模块的命名约定

在 Go 中,模块名称在系统范围内使用,因此应该尽可能具体,特别是如果您计划将模块分发给其他开发人员。模块名称在文件中指定go.mod,该文件充当模块的清单,位于模块目录层次结构的根部。

以下是 Go 中模块命名的一些准则:

模块路径:模块路径应该是模块的全局唯一标识符。它通常采用倒序的 Internet 域名形式,后跟模块名称。例如,github.com/littlejohnny65/example-module。从模块导入包时,模块路径用作导入路径。

模块名称:模块名称是模块路径的最后一个组成部分。它应该简短、具有描述性,并遵守 Go 的命名约定。建议使用不带下划线或混合大写的小写字母。例如,examplemodule

版本控制:模块名称本身不包含版本信息。模块的版本在go.mod文件中使用模块版本标识符单独指定,例如v1.2.3. 模块路径和版本标识符的组合唯一标识模块的特定版本。

为模块选择有意义和描述性的名称很重要,因为它们是公开可识别的,并且可以在其他项目中用作依赖项。清晰一致的命名约定有助于理解模块的用途和上下文。

go.sum 文件

当您运行类似 的命令时go get github.com/user/repo,Go 工具将从该位置获取模块。这使得在任何支持版本控制系统(如 Git、Mercurial、Bazaar 或 Subversion)的服务器上托管 Go 代码成为可能。

Go 有一种非常灵活和直接的方法来从外部存储库下载依赖项。所以为了保证依赖的完整性所采用的解决方案是创建一个本地文件来存储每个依赖的校验和。这是保证安装的依赖项完全相同的原因。

校验和文件由本地 Go 工具生成。如果您想确保依赖项与本地环境中的依赖项完全相同,则应将其推送到服务器和 Dockerfiles 等外部环境。

模块化 Go 项目的文件树

 /home/user/projects/
 └── myapp/                         # Your project
    ├── custom/                   # Custom packages
        └── ...                         # .go files defining functionality
    ├── go.mod                     # go.mod file defining dependencies & versions
    ├── go.sum                     # go.sum file that verifies dependency integrity
    └── main.go                   # Entrypoint

模块缓存的文件树,假定默认的 GOPATH 路径:

 /home/user/go/        # This is your GOPATH
 └── pkg/
    └── mod/
        └── cache/
            └── download/
                └── github.com/
                    └── someuser/
                        └── somelib/     # Source code of the dependency
                            └── somelib.go

在这个结构中:

  • 您的项目可以存在于文件系统中的任何位置。它包含一个 go.mod 文件和一个 go.sum 文件。

  • go.mod 文件列出了您的项目使用的依赖项的特定版本。

  • go.sum 文件在将每个依赖项添加到模块时提供其确切内容的校验和。

  • 依赖项存储在 Go 模块缓存中,它在系统上的所有项目之间共享。

模块 CLI 命令

有几个方便的命令可用于处理模块化 Go 项目:

go mod init: 在当前目录中初始化一个新模块。它创建一个go.mod定义模块路径的文件并将其设置为依赖管理。

go mod tidy:从文件中添加缺失和删除未使用的模块和依赖项go.mod。它确保go.mod文件准确反映项目所需的依赖项。

go mod download:下载文件中定义的依赖项go.mod,并将它们存储在模块缓存中。它获取项目所需的特定版本的依赖项。

go mod vendor:将依赖项复制到vendor项目中的目录中。当您想要创建一个包含其所有依赖项的独立项目时,此命令很有用。

go mod verify:验证模块缓存中的依赖项是否与go.sum文件中指定的预期加密校验和匹配。它确保下载的依赖项的完整性和真实性。

go mod graph:打印模块依赖图,显示模块及其版本之间的关系。它对于理解项目依赖项的整体结构很有用。

go mod edit:提供一系列用于对文件进行手动编辑的子命令go.mod。它允许您添加、删除或更新模块要求、替换模块等。

这些只是一些常用的go mod命令。go help mod您可以通过运行或参考关于模块的官方 Go 文档来探索更多命令及其选项。

包起来

模块化方法与单一工作区并无根本区别或不兼容。但它建立在它的基础上,以带来更多的灵活性和可管理性。

模块允许您在文件系统中的任何地方拥有一个项目,并且还具有命名空间依赖性以获得更好的稳定性。但它仍然使用 GOPATH 作为默认位置来存储依赖项和可执行文件。

总之,go.mod 提供的模块化环境是 Go 开发者工具箱中的一个强大工具,补充和扩展了传统 GOPATH 环境的功能。它标志着 Go 适应了现代软件开发的复杂性和规模不断增加,展示了该语言为满足其用户不断变化的需求而不断发展。

随着我们的前进,想象一下 Go 生态系统的未来发展将会令人兴奋。

https://www.java567.com,搜"go")

标签:GOPATH,依赖,Golang,Go,vs,模块,go,mod
From: https://www.cnblogs.com/web-666/p/17437984.html

相关文章

  • Postgres vs MySQL
    主要区别及示例简而言之,Postgres和MySQL之间的主要区别实际上归结为主索引和辅助索引的实现方式以及数据的存储和更新方式。让我们进一步探讨这个问题。但首先...基础知识索引是一种数据结构(主要是B+树),允许通过多层节点进行键的搜索,数据库将其实现为页面。树的遍历允许消除不包......
  • kube-proxy的iptables与ipvs模式性能对比与分析
    kube-proxy的iptables与ipvs模式性能对比与分析背景:iptables代理模式iptables是一个Linux内核功能,旨在成为一种高效的防火墙,具有足够的灵活性来处理各种常见的数据包操作和过滤需求。它允许将灵活的规则序列附加到内核数据包处理管道中的各种钩子上。在iptables模式下,kube-p......
  • vSphere VCSA 6.7的搭建
    VCSA6.7搭建总是失败,最后总结是DNS解析的问题。步骤:一、下载VCSA安装包,挂载,这个步骤就没什么说的啦。二、第一步的安装,这里也基本没问题,但是涉及到后面是否安装成功,配置还是要不按照常规修改下。配置网络设置页面:FQDN填写VCSA的ip地址,DNS服务器也填写VCSA的ip地址,第一步按照默认安......
  • 文心一言 VS 讯飞星火 VS chatgpt (23)-- 算法导论4.2 5题
    五、V.Pan发现一种方法,可以用132464次乘法操作完成68x68的矩阵相乘,发现另一种方法,可以用143640次乘法操作完成70x70的矩阵相乘,还发现一种方法,可以用155424次乘法操作完成72x72的矩阵相乘。当用于矩阵相乘的分治算法时,上述哪种方法会得到最佳的渐近运行时间?与......
  • 文心一言 VS 讯飞星火 VS chatgpt (23)-- 算法导论4.2 5题
    五、V.Pan发现一种方法,可以用132464次乘法操作完成68x68的矩阵相乘,发现另一种方法,可以用143640次乘法操作完成70x70的矩阵相乘,还发现一种方法,可以用155424次乘法操作完成72x72的矩阵相乘。当用于矩阵相乘的分治算法时,上述哪种方法会得到最佳的渐近运行时间?与......
  • [golang]gin框架接收websocket通信
    前言WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket让客户端和服务端之间的数据交换变得非常简单,且允许服务器主动向客户端推送数据,并且之后客户端和服务端所有的通信都依靠这个专用协议进行。本文使用gin框架编写服务端应用,配置路由接收websocket请求并处理。......
  • vscode配置C/C++调试环境
    1.Ctrl+Shift+P,输入tasks,选择"Tasks:ConfigureDefaultBuildTask",z这会生成tasks.json.然后,修改其中的args,删掉原来的${file},并将工程下的c文件添加进去,即${fileDirname}/*c(或单个文件添加也行,笔者因为工程的所有的c文件都在一个路径下,所以用的*.c):1{......
  • ProlificDreamer(VSD) 论文阅读笔记
    这是一篇textto3D方向的突破性的文章,效果确实非常棒,据说一作的朋友圈中也说“他们将这个领域从20分提升到了70分的水平”,预测之后会有许多基于该方法的优秀文章与产品出现,毕竟之前SDSfollow的文章也有很大一批。本阅读笔记就简要去记录一下这篇论文的主要方法和思想。Var......
  • 使用vscode远程连接Linux环境写C程序
    1. 下载安装vscode2. 在扩展商店搜索chinese安装中文语言包, 相当于汉化vscode, 应该需要重启生效3. 安装配置插件RemoteSSH4. 连接远程主机, 在资源管理器中可以管理文件5. 试着创建一个文件, 以.c作为扩展名, 会自动下载插件c/c++扩展包6. 写好的C程序, 可以......
  • 去除Flutter项目dart文件在vscode里出现波浪号
    问题示例: 去掉Flutter项目在vscode里打开显示的蓝色波浪线解决办法: ......