GO语言工程实践 | 青训营

81 阅读5分钟

这是我参与第六届字节跳动青训营后端班的第2篇笔记,和上一篇一样,应该很早就发的,是不才拖延症选手拖到现在才整理笔记。此篇笔记梳理Go语言实战部分内容,此部分内容比较多,为避免篇幅过长,第三个例子和课后作业部分内容放到下一篇笔记。

猜谜游戏

课程的第一个例子,使用 Golang 来构建一个猜数字游戏。在这个游戏里面,程序首先会生成一个介于 1 到 100 之间的随机整数,然后提示玩家进行猜测。玩家每次输入一个数字,程序会告诉玩家这个猜测的值是高于还是低于那个秘密的随机数,并且让玩家再次猜测。如果猜对了,就告诉玩家胜利并且退出程序。 image.png 可以看到,当程序运行的时候会生成一个 0 到 100 之间的随机数字。

首先来生成这个随机数。生成随机数需要用到 math/rand 包。我们先导入 FMT 包和 math/rand 包,定义一个变量, max_num 是100。根据这个包的文档,我们使用它之前需要设置随机数种子,否则的话每一次都会生成相同的随机数序列。一般惯例用法是在程序启动的时候,用启动的时间戳来初始化随机数种子。然后用 rand.Intn 来生成一个随机数,再打印出这个随机数。 image.png

然后需要实现用户输入输出,并解析成数字。我们用reader变量的 ReadString 方法来读取一行输入。读取失败则打印错误并退出。ReadString 返回的结果包含结尾的换行符,我们把它去掉并转换成数字。同样如果转换失败就打印错误、退出。 image.png

接下来实现判断逻辑。现在已经有了一个秘密的值,然后也从用户的输入里面读到了一个值,要来比较这两个值的大小。如果是用户输入的值比那个秘密的值要大的话,就告诉用户猜的值太大了,请再试一次。如果是小了也同理,如果是相等的话,就告诉用户赢了。 image.png

然后要实现游戏的循环,否则用户只能输入一次猜测,且无论猜测是否正确,程序都会突退出。为了让游戏可以正常玩下去,需要加一个循环。把现有的代码挪到一个 for 循环里面,再把 return 改成 continue 以便于在出错的时候能够继续循环。在用户输入正确的时候 break ,这样就能够在用户胜利的时候退出游戏。 image.png 至此,采用Golang实现的猜谜游戏成功构建完成。

在线词典

第二个例子更复杂一点,是一个命令行排版的词典。 image.png 用户可以在命令行里面查询一个单词,我们通过调用第三方的 API 查询到单词的翻译并打印出来。这个例子里面,我们会学习如何用 Go 语言来发送 HTTP 请求、解析json,还会学习如何使用代码生成来提高开发效率。

首先是要用到的 API,以彩云科技提供的在线翻译为例。打开彩云翻译的网页,然后右键检查打开浏览器的开发者工具。 image.png 然后点一下翻译按钮,浏览器会发送一系列请求,找到那个用来查询单词的请求。这是一个 HTTP 的 post 的请求,API 的返回结果里面会有 Wiki 和 dictionary 两个字段。我们需要用的结果主要在dictionary.Explanations 字段里面。 image.png 要在 Golang 里面去发送这个请求,可以用一种非常简单的方式来生成代码,右键浏览器里面的 copy as curl。 copy完成之后在终端粘贴一下 curl 命令,可以成功返回一大串 json。 image.png 然后打开这个代码生成网站curlconverter.com/#go ,粘贴 curl 请求,在右边的语言里面选 Golang 就能够看到一串很长的代码,直接把它 copy 到我们的编辑器里面。生成代码有转义导致的编译错误删掉即可。 image.png 然后来运行生成的代码,能看到已经能够成功地发出请求,把返回的 JSON 打印出来。但是现在那个输入是固定的,要从一个变量来输入需要用到 JSON 序列化。

先构造一个包含三个字段的结构体,再定义一个变量,初始化每个结构体成员,再调用 JSON.marshaler 来得到这个序列化之后的字符串。不同于之前这里是个字符串,这里是个字节数组。所以把 strings.newReader 改成 bytes.new ready 来构造 request 上的 body 。然后就能成功地通过一个变量来发送 HTTP 请求。 image.png 接下来要把这个 response body 来解析出来。和request一样,写一个结构体,把返回的JSON反序列化到结构体里面。这里用到另一个代码生成工具,打开oktools.net/json2go ,把json字符串粘贴进去,就能够得到对应response结构体。

接下来回到代码,定一个 response 结构体的对象,然后用 JSON.unmarshal 把 body 反序列化到这个结构体里面,再打印出来。 image.png 然后我们要打印 response 里面的特定字段。观察 json 可以看出我们需要的结果是在 Dictionary.explanations,用 for range 循环来迭代它,然后直接打印结构,参照一些词典的显示方式,可以在前面打印出这个单词和它的音标。 image.png 现在程序的输入还是写死的。要把代码的主体改成一个query函数,查询的单词作为参数传递进来。 image.png 最后写一个简单的 main 函数,首先判断一下命令和参数的个数,如果不是两个,就打印出错误信息,退出程序。否则就获取到用户输入的单词,然后执行 query 函数。 image.png 至此,命令行词典完成。