Go如何创建一个包并使用(导入本地包和注意事项)

Go 语言中,包(Package)的目的和其他语言中的库或模块是一样的,支持模块化、封装、单独编译和重用。 ——《The Go Programming Language》

有时候需要自己写一个包方便多次使用,但是在导入自己写的包时遇到了问题。我以前以为import部分直接就是包的路径,但是实际自己写了之后发现不是这样的。这部分实际上这部分是可以解释成一个标识符,是由一个go.mod文件确定,一般含义确实是路径末端。

Go 中模块的概念其实还包含了一部分版本管理的功能。所以 Go 的模块和版本管理无论是学习还是开发都不是一件容易的事情,Go 团队也在一直努力调整和优化。本文只能代表当前版本go1.20.2版本的情况,如果未来更新了我会进行备注。

go.mod是什么

每个 Go 的模块都是由go.mod确定,该文件描述了模块的属性,例如模块存放的路径是否依赖其他模块、最低使用 Go 版本等信息。比如mod@v0.8.0go.mod内容为:

module golang.org/x/modgo 1.17require golang.org/x/tools v0.1.12 // tagx:ignore

然后在编译的时候,编译器会去找有没有这个标识这个模块的go.mod,如果有的话找到对应的xxx.go,然后导入相应的包中使用的功能进行编译。

这里有两个问题:

  1. Go 在哪找模块的?
  2. 如何让 Go 从特定目录下搜索包?

模块(module)和包(package)的区别在于:模块是一系列包的集合,并且在模块文件结构的根目录下有个go.mod文件,自己甚至可以直接被编译成一个程序。而包是某一个或多个.go文件,用来划分包级别的作用域(package level),可以当做其他语言的库。范围应该是:模块>>>包>>>源代码文件。但是在某些情况下,包、模块、库这三个词是可以混用的(在不同情况下叫法不同,但是却指同一个东西)。
需要注意package main是个例外,这并不是一个库(尽管开头有个package),而是用来表示这是个可以单独执行的程序。

创建模块和编写包的内容

这里举个例子来进行演示,演示的例子来自《The Go Programming Language》中 Section 2.7,是用来数一个数的二进制有多少位为1,比如输入1返回1,输入0x1234567890ABCDEF返回32

新建一个文件夹popcount,然后在里面创建一个名为popcount.go的文件:

$ mkdir popcount
$ cd popcount
$ touch popcount.go

输入以下内容(下面这个算法不是最快的,也不是最容易理解的,但是可以解释很多东西):

package popcount// pc[i]用来计数第i位是不是
var pc [256]byte
//初始化包
func init() {for i := range pc {pc[i] = pc[i/2] + byte(i&1)}
}// PopCount返回x有多少位为1.
func PopCount(x uint64) int {return int(pc[byte(x>>(0*8))] +pc[byte(x>>(1*8))] +pc[byte(x>>(2*8))] +pc[byte(x>>(3*8))] +pc[byte(x>>(4*8))] +pc[byte(x>>(5*8))] +pc[byte(x>>(6*8))] +pc[byte(x>>(7*8))])
}

上文中:pc首字母是小写的,所以只能在popcount包中使用,而PopCount首字母是大写的,所以可以在导入popcount包的文件中使用。

继续在popcount中通过go mod init命令创建go.mod文件,如下:

$ go mod init test/popcount
go: creating new go.mod: module test/popcount
go: to add module requirements and sums:go mod tidy
$ ls
go.mod		popcount.go

可以看到多了个go.mod文件。

导入自建包(本地包)

然后在其他地方新建一个目录pop_test来编写使用这个包的程序代码(可以和popcount在同一个目录下,或者其他地方都行),这里选择和popcount在同一个目录下,如下:

$ cd ..
$ mkdir pop_test

然后在pop_test中新建一个go.mod

$ go mod init pop_test

这时候go.mod的内容应该是如下样式:

module pop_testgo 1.20

用你喜欢的文本编辑器打开它,在末尾添加这样两句话,变成如下样式:

module pop_testgo 1.20require test/popcount v0.0.0
replace test/popcount => ../popcount

最后这两句都不能省略,少一句都不行。

第一句是为了说明使用popcount的版本,第二句是因为我们使用的是本地包(local package),而不是下载导入的库,本地包的位置并不在GOROOT/src/test/popcount中,Go 编译的时候找不到的(关于GOROOT后面还有一些内容)。第二句话其实类似于 C 编译器中的选项-I。(这里解决了开头的那两个问题)

然后新建一个main.go文件,输入以下内容:

package mainimport ("fmt""test/popcount"
)func main() {a := popcount.PopCount(0x1234567890ABCDEF)fmt.Println(a)
}

这时候运行应该看到以下结果:

$ go run main.go 
32

这种方法是官方推荐的,但是问题在于要在项目的根目录(如上的pop_test)下创建一个go.mod

第二种方法

下面这种方法是根据运行机制进行设置的,说实话并不是很方便管理,但是某些情况下却挺方便的。

上文中提到:Go 默认是在GOROOT/src下寻找包的,某个包就是GOROOT/src/包名。那么就可以直接在GOROOT/src下按照包名的结构放置自建的本地包,然后就可以在程序代码中直接使用了,不用再在项目根目录下创建一个go.mod文件来说明使用的本地包的位置了。

通过以下命令找到你的GOROOT,如下:

$ go env GOROOT
/usr/local/go

你的可能不是/usr/local/go。对于 Go 的这些环境变量最好使用go env查看,如果你使用echo $GOROOT可能会发现这个环境变量是空的。

此外,最好不要用expert在 Shell 配置文件中修改这个环境变量,因为标准库都在默认的GOROOT中,一旦你切换了,那么这些标准库你最好都复制到新位置。特殊情况下直接用expert修改,但是只在当前终端切换,不要彻底替换。

这种方法的最大弊端在于修改了/usr/local/go,这些默认目录大部分时期是通过脚本自动操作配置的,如果你进行了修改,那么未来可能会出现问题和冲突,而你又忘了修改了这部分,那就是个很大的问题了。

所以如果必须用这种方法,最好创建一个不会重名(或者概率不大)的文件夹,比如ZhongUncle,然后在里面创建包和配置go.mod

希望能帮到有需要的人~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/129941.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

框架安全-CVE 复现Apache ShiroApache Solr漏洞复现

文章目录 服务攻防-框架安全&CVE 复现&Apache Shiro&Apache Solr漏洞复现中间件列表常见开发框架Apache Shiro-组件框架安全暴露的安全问题漏洞复现Apache Shiro认证绕过漏洞(CVE-2020-1957)CVE-2020-11989验证绕过漏洞CVE_2016_4437 Shiro-…

城市内涝解决方案:实时监测,提前预警,让城市更安全

城市内涝积水问题是指城市地区在短时间内遭遇强降雨后,地面积水过多,导致城市交通堵塞、居民生活不便、财产损失等问题。近年来,随着全球气候变化和城市化进程的加速,城市内涝积水问题越来越突出,成为城市发展中的一大…

基于设深度学习的人脸性别年龄识别系统 计算机竞赛

文章目录 0 前言1 课题描述2 实现效果3 算法实现原理3.1 数据集3.2 深度学习识别算法3.3 特征提取主干网络3.4 总体实现流程 4 具体实现4.1 预训练数据格式4.2 部分实现代码 5 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 基于深度学习机器视觉的…

软件测试/测试开发丨ChatGPT能否成为PPT最佳伴侣

点此获取更多相关资料 简介 PPT 已经渗透到我们的日常工作中,无论是工作汇报、商务报告、学术演讲、培训材料都常常要求编写一个正式的 PPT,协助完成一次汇报或一次演讲。PPT相比于传统文本的就是有布局、图片、动画效果等,可以给到观众更好…

【leetcode】26. 删除有序数组中的重复项(图解)

目录 1. 思路(图解)2. 代码 题目链接: leetcode 26. 删除有序数组中的重复项 题目描述: 注意返回的是去重后的数组长度,但是输出的是去重后的数组元素。 1. 思路(图解) 思路:快慢…

在maven官网中如何下载低版本的maven

链接:https://archive.apache.org/dist/maven/maven-3/

[笔记] 数据类型

整形 一字节(Byte,也就是平时KB、MB里面的B)就是八个二进制位(bit) 整形——int——4B无符号整形——unsigned int——4B短整形——short——2B长整型——long——4B双长整型——long long——8B 浮点型 参考博客:C 语言的浮点类型…

快速了解相似检索方法

一、相似检索方法总体分析 相似检索方法是一种用于从大量数据中找到与查询数据相似的数据项的技术。这种方法通常用于信息检索、推荐系统、图像处理、自然语言处理等领域。相似检索主要方法可以总体分为以下几类: 基于距离度量的方法: 余弦相似度&…

Postman接口测试工具,提高SpringBoot开发效率

文章目录 🌺工具—postman⭐作用🏳️‍🌈安装🎈创建工作空间 🎄简单参数⭐原始方式🎈我们建立springboot项目,输入下面的代码🎈运行 ⭐SpringBoot方式 🎄实体参数&#x…

正点原子嵌入式linux驱动开发——Linux 音频驱动

音频是最常用到的功能,音频也是linux和安卓的重点应用场合。STM32MP1带有SAI接口,正点原子的STM32MP1开发板通过此接口外接了一个CS42L51音频DAC芯片,本章就来学习一下如何使能CS42L51驱动,并且CS42L51通过芯片来完成音乐播放与录…

Day39 QTableWidget类的使用

1.简介 介绍QtableWidget各种属性的用法,以及常用的一些信号,最后利用这些特性,制作一个用于下发设备运行参数的表格。该表格可以实现折叠和取消折叠,在源代码中用了事件过滤器实现,也可以用自带的click信号。显示了图…

VPC划分子网

划分子网 A类网络:0000—127.255.255.255 B类网络:128000—191.255.255.255 A,B类一般是公网 C类网络:192.0.0.0—223.255.255.255 C类一般是私网 子网subnet 192.168.0.0/24这个子网中:192.168.0.0默认是标识整个子…

“第五十九天”

这是昨天那道题,这个后面自己的处理思路还是差了点,这道题关键感觉就是对进位的处理的,由于进位的存在,所以处理数据的时候只能从最低位开始,我一开始是从高位处理的,而且后面越来越迷,这个点一…

自家开发VS第三方美颜SDK:技术和资源的比较

开发直播平台时,开发人员面临一个关键决策:是选择使用第三方美颜SDK,还是自家开发美颜算法?本文将深入探讨这两种方法的技术和资源方面的比较,帮助开发者更好地决定哪种途径最适合他们的应用。 一、第三方美颜SDK&am…

智能电表和互感器一起安装有什么效果?

智能电表和互感器的普及,为用电管理提供了更为精确和便捷的方式。那么,当智能电表和互感器一起安装时,会产生怎样的"化学反应"呢?下面,小编就来为大家详细的讲解下智能电表和互感器一起安装的作用吧&#xf…

git的命令操作

1、基本命令 目录 1、基本命令 创建 Git 存储库 添加文件/目录到索引 将更改提交到本地存储库 撤消上一次提交的更改 显示工作树状态 显示对工作树和索引的更改 显示提交日志 显示提交详细信息 重命名文件 从工作树和索引中移除文件 从工作树中移除未跟踪文件 将…

lua-web-utils库

lua--导入所需的库local web_utilsrequire("lua-web-utils")--定义要下载的URLlocal url"https://jshk.com.cn/"--定义代理服务器的主机名和端口号local proxy_port8000--使用web_utils的download函数下载URLlocal file_pathweb_utils.download(url,proxy_…

2023最新C语言编程练习题大全(一)

目录 一、初识C语言1.1 第一个C语言程序1.2 一个完整的C语言程序1.3 输出名言1.4 计算正方形的周长 二、一个简单的C语言程序2.1 输出一个正方形2.2 输出直角三角形2.3 设计一个简单的求和程序2.4 求10!2.5 三个数由小到大排序2.6 猴子吃桃2.7 阳阳买苹果 一、初识C语言 1.1 第…

MATLAB 绘制 SISO 和 MIMO 线性系统的时间和频率响应图

系列文章目录 文章目录 系列文章目录前言一、时间响应二、频率响应三、极点/零点图和根节点四、响应特性五、分析 MIMO 系统六、系统比较七、修改时间轴或频率轴数值如果觉得内容不错,请点赞、收藏、关注 前言 本例演示如何绘制 SISO 和 MIMO 线性系统的时间和频率…

设计模式04———桥接模式 c#

桥接模式:将一个事物从多个维度抽象出来,采用 分离 和 组合 的方式 替代 原本类的继承 桥接模式(Bridge Pattern)是一种软件设计模式,属于结构型模式,它用于将抽象部分与具体实现部分分离,以便它…