当前位置: 首页 > news >正文

在Go中导入软件包

引言

对于任何广泛使用的编程语言,乃至整个开源社区来说,在不同项目之间借用和共享代码的能力都是基础。借用代码使程序员能够将大部分时间花在针对自己的需求编写代码上,而且通常他们的一些新代码最终会对其他人有用。然后他们可能决定将这些可重用的部分组织成一个单元,并在他们的团队或更广泛的编程社区中共享它。

在Go中,可重用代码的基本单元称为。即使最简单的Go程序也是它自己的包,并且可能使用至少一个其他包。在本教程中,你将编写两个小程序:一个使用标准库包来生成随机数,另一个使用流行的第三方包来生成UUID。然后,您可以选择编写一个较长的程序来比较两个相似的标准库包,导入并使用这两个包,即使它们具有相同的基本名称。最后,您将使用goimports工具来查看如何格式化导入。

注意: Go中还有一个更高级别的可重用代码单元:module。模块是包的版本化集合。您将在后面的文章“如何使用Go模块”中探索模块

前期准备

在开始本教程之前,您只需要安装Go。

步骤1 -使用标准库包

与大多数语言一样,Go有一个内置的可重用代码库,您可以将其用于常见任务。例如,你不需要编写自己的代码来格式化和打印字符串,或者发送HTTP请求。Go标准库为这些任务和许多其他任务提供了软件包。
[如何用Go编写第一个程序]中的程序使用了标准库中的fmtstrings包。让我们再写一个程序,使用math/rand包来生成一些随机数。
nano或者你喜欢的文本编辑器中打开一个名为random.go的新文件:

nano random.go

下面来创建一个程序,打印5个从0到9的随机整数。将以下内容粘贴到编辑器中:

package mainimport "math/rand"func main() {for i := 0; i < 5; i++ {println(rand.Intn(10))}
}

这个程序导入了’math/rand’包,并通过引用其基本名称rand来使用它。这是出现在包中每个Go源文件顶部的package <pkgname>声明中的名称。

for循环的每次迭代都会调用rand.Intn(10)来生成一个介于0到9之间的随机整数(不包括10),然后将该整数打印到控制台。
请注意,对println()的调用没有引用包的名称。这是一个不需要导入的内置函数。通常你会使用fmt包中的fmt.Println()函数,但这个程序使用println()来引入内置函数。

保存程序。如果你使用的是nano,按下CTRL+X,然后YENTER来确认你的更改。然后运行程序:

go run random.go

你将看到从0到9的5个整数:

Output1
7
7
9
1

看起来随机数生成器正常工作了,但请注意,如果你反复运行程序,它每次打印的都是相同的数,而不是你预期的新随机数。这是因为我们没有调用rand.Seed()函数来用一个唯一的值初始化数字生成器。如果你不这样做,该包的行为就像调用了rand.Seed(1)一样,因此它每次都会生成相同的“随机”数字。

因此,每次程序运行时,你都需要为数字生成器提供一个唯一的值。程序员通常使用以纳秒为单位的当前时间戳。为此,你需要time包。在编辑器中再次打开random.go并粘贴以下内容:

package mainimport ("math/rand""time"
)func main() {now := time.Now()rand.Seed(now.UnixNano())
println("Numbers seeded using current date/time:", now.UnixNano())for i := 0; i < 5; i++ {println(rand.Intn(10))}
}

当导入多个包时,可以使用括号来创建导入块。通过使用块,你可以避免在每一行上重复import关键字,这使你的代码更简洁。
首先,你通过time.Now()函数获取当前系统时间,该函数返回一个time 结构体。然后你将时间传递给rand.Seed()函数。该函数需要一个64位整数(int64),所以你需要在now结构体上使用Time.UnixNano()方法来传递以纳秒为单位的时间。最后,打印生成随机数所需的时间。

现在保存并再次运行程序:

go run random.go

你应该会看到类似下面的输出:

OutputNumbers seeded using current date/time: 1674489465616954000
2
6
3
1
0

如果你运行这个程序几次,每次都应该看到不同的整数,以及用于生成随机数的唯一整数。

让我们再编辑一次程序,以更友好的格式打印种子时间。编辑包含第一个println()调用的那行代码,如下所示:

	println("Numbers seeded using current date/time:", now.Format(time.StampNano))

现在你正在调用Time.Format()方法,并传入在time包中定义的多种格式中的一种。time.StampNano常量(const)是一个字符串,将它传递给Time.Format()可以让你打印月份、日期和时间,精确到纳秒。保存并再次运行程序:

go run random.go
OutputNumbers seeded using current date/time: Jan 23 10:01:50.721413000
7
6
3
7
3

这比看到一个表示自1970年1月1日以来经过的纳秒数的巨大整数要好。

如果您的程序不需要随机整数,而是需要UUID,许多程序员使用它作为其部署中数据片段的全局唯一标识符,该怎么办?Go标准库没有生成这些内容的软件包,但社区提供了。现在让我们看看如何下载和使用第三方包。

步骤2 -使用第三方软件包

生成uuid最流行的包之一是github.com/google/uuid。第三方包总是通过它们的全限定名称来知道,其中包括托管代码的网站(例如github.com),开发它的用户或组织(例如谷歌),以及基本名称(例如uuid)。在导入包时,在pkg.go.dev和其他地方阅读它的文档时,您将使用它的全限定名称。但是,在代码语句中引用它时,只能使用基本名。

在下载包之前,您需要初始化一个模块,这是Go管理程序的依赖项及其版本的方式。要初始化一个模块,请使用go mod init并传入你自己的包的全限定名称。如果你想在GitHub上以用户名“sammy”托管你的模块,可以像这样初始化模块:

go mod init github.com/sammy/random

这将创建一个名为go.mod的文件。让我们看看这个文件:

cat go.mod

相关文章:

  • 软件设计师——计算机网络(二)
  • 大数据技术7:基于StarRocks统一OALP实时数仓
  • JavaScript强制类型转换
  • TSINGSEE青犀中央厨房视频智能监控监管解决方案
  • SSD基础架构与NAND IO并发问题探讨
  • GeoTools学习笔记
  • 雅典娜Athena-signa音频算法源码与麦克风阵列角度定义互换问题
  • 【uniapp小程序】如何根据开发和发行,自动替换不同环境的baseUrl
  • strings
  • RocketMQ源码 Broker-SubscriptionGroupManager 订阅组管理组件源码分析
  • fastapi-amis-admin快速创建一个后台管理系统增加音乐管理功能(3)
  • 前端接入若依后,页面白屏问题排查
  • 玩转大数据11:数据可视化与交互式分析
  • scala编码
  • 《算法面试宝典》--机器学习常见问题汇总
  • 2017-08-04 前端日报
  • Angular 4.x 动态创建组件
  • ES6, React, Redux, Webpack写的一个爬 GitHub 的网页
  • gf框架之分页模块(五) - 自定义分页
  • IDEA 插件开发入门教程
  • JAVA SE 6 GC调优笔记
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • Python爬虫--- 1.3 BS4库的解析器
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • 百度小程序遇到的问题
  • 彻底搞懂浏览器Event-loop
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • ------- 计算机网络基础
  • 紧急通知:《观止-微软》请在经管柜购买!
  • 入门级的git使用指北
  • 什么软件可以提取视频中的音频制作成手机铃声
  • 智能合约开发环境搭建及Hello World合约
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • ​软考-高级-系统架构设计师教程(清华第2版)【第1章-绪论-思维导图】​
  • ​业务双活的数据切换思路设计(下)
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • $emit传递多个参数_PPC和MIPS指令集下二进制代码中函数参数个数的识别方法
  • (1) caustics\
  • (4) PIVOT 和 UPIVOT 的使用
  • (C++20) consteval立即函数
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (九)c52学习之旅-定时器
  • (论文阅读32/100)Flowing convnets for human pose estimation in videos
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (译)2019年前端性能优化清单 — 下篇
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .
  • **PHP二维数组遍历时同时赋值
  • .apk文件,IIS不支持下载解决
  • .Net Redis的秒杀Dome和异步执行
  • .NET Standard 支持的 .NET Framework 和 .NET Core
  • .net 生成二级域名
  • .NET/C# 中你可以在代码中写多个 Main 函数,然后按需要随时切换