GO语言实战案例 | 青训营笔记

119 阅读4分钟

章节介绍

本章节主要介绍了,使用Golang语言来实现3个简单的案例。在上节课的学习当中,了解了Golang语言的变量类型、函数、结构体、字符串处理、时间、进程管理等知识,本节课,我们将利用所学的这些知识来写案例。接下来,让我们进入案例的学习吧。

案例一:猜数字游戏

游戏简介:系统随机生成一个未知的数字,玩家多次进行猜测,每次给出猜测时,程序回答玩家大小。

1.怎么生成随机数?

首先我们需要在import中导入"fmt"与"math/rand"两个包

然后我们可以在func main(){}中进行编辑

生成随机数的主要代码包括

	maxNumber := 100
	rand.Seed(time.Now().UnixNano())
	secretNumber := rand.Intn(maxNumber)
	fmt.Println("The secretnumber is", secretNumber)

在视频教程当中,克纯老师讲到了若不添加rand种子,会导致每次输出的随机数都是一样的

2.读取用户的输入输出

在输入输出模块我们需要导入的包逐渐多了起来,但在插件的作用下,我们不需要手动去更改import,做到了随用随导。 我们总共添加了 "bufio" "fmt" "math/rand" "os" "strconv" "strings" "time"这些包。

我们直接上核心代码

	// 用户的输入输出
	fmt.Println("Please input your guess:")
	reader := bufio.NewReader(os.Stdin)
	input, err := reader.ReadString('\n')
	if err != nil {
		fmt.Println("One error occured while reading input,please try again")
		return
	}
	input = strings.TrimSuffix(input, "\n")
	input = strings.TrimSuffix(input, "\r")
	guess, err := strconv.Atoi(input)
	if err != nil {
		fmt.Println("Invaild input,Please enter an integer value")
		fmt.Println(err)

	}
	fmt.Println("Your guess is ", guess)

在代码当中我们看到了新的东西,在这里逐一介绍:

reader := bufio.NewReader(os.Stdin)

1.bufio.NewReader :查看文档解释为返回一个新的 Reader,其缓冲区具有默认大小。

2.os.Stdin :读入输入流

input, err := reader.ReadString('\n')

1.reader.ReadString :读入第一行

input = strings.TrimSuffix(input, "\n")

input = strings.TrimSuffix(input, "\r")

用来将input中指定元素删除,案例中输入数字后回车,需要加入\r,否则字符串为“num\r” ,依旧 无法转化为数字。否则我们将err打印一下试试,如下图:

image.png

剩下的就是简单的判断和循环逻辑,不在此处展示。

关于作业我们使用fmt.Scanf("%d",&guess)实现,页面免去流的读取,过滤,类型转换等代码。

案例二:在线词典

在线辞典案例,主要练习的是结构体、对json数据的相关处理以及http请求等。

在这个案例中,主要实现的功能是通过终端命令敲入单词,发送request请求获取音标和解释并输出出来。

我们用到的单词翻译网站是彩云小译 - 在线翻译 (caiyunapp.com)

1.如何用Go来发起request?拿到response?

我们打开F12开发者工具,在单词输入去敲入good,可以找到相关的POST请求:

image.png

随后右键我们网页的请求,复制cUrl

image.png 拿到网页Convert curl to go中去解析生成发起POST请求的Golang代码

image.png

在生成的代码当中,我们可以看到string.NewReader了一个json,这个其实就是网站当中的发送POST请求的标准格式:

image.png http.NewRequest生成了一个POST请求,再往后面生成的一大段req.Header.Set就是设置请求头的部分,然后再通过resp,err:=client.Do(req)来发起请求,并将response数据存入resp,后面出现了io.ReadAll,查询文档得知作用为 从 r 读取直到出现错误或 EOF 并返回它读取的数据。 成功的调用返回错误 == nil,而不是错误 == EOF。因为 ReadAll 是 定义为从 src 读取到 EOF,它不处理从读取的 EOF 作为要报告的错误,那么接下来有了大体框架,我们需要对输入和输出做进一步的规范。

2.规范request

我们创建一个这样的结构体

type DictRequest struct {
	TransType string `json:"trans_type"`
	Sourse    string `json:"source"`
	UserID    string `json:"user_id"`
}

回应请求中的source和trans_type,后面的json:"XXX"一定要与实际中的请求json属性名一致! 然后我们将NewReader的过程改造成这样实现:

request := DictRequest{TransType: "en2zh", Sourse: word}
buf, err := json.Marshal(request)
//通过json.Marshal来将我们的DictRequst序列化
var data = bytes.NewReader(buf)

3.规范response

这一部分就是对响应回来的数据进行处理,所有的数据并不都是我们想要的

image.png 而且想应用这些数据需要把json转换成其他形式,比如结构体。

我们可以通过 JSON转Golang工具来进行转换:

image.png

关于怎么复制?我们可以通过golang的输出进行复制也可以在这里进行复制:

image.png

将生成的结构体搬到我们的golang当中 然后通过如下代码对数据进行规范

	var dictResponse DictResponse
	err = json.Unmarshal(bodyText, &dictResponse)
	if err != nil {
		log.Fatal(err)
	}
	// fmt.Printf("%+v\n", dictResponse)
	if dictResponse.Dictionary.Prons.En == "" {
		fmt.Println("not exist!")
		return
	}
	fmt.Println(word, "UK:", dictResponse.Dictionary.Prons.En, "US:", dictResponse.Dictionary.Prons.EnUs)
	for _, item := range dictResponse.Dictionary.Explanations {
		fmt.Println(item)
	}

其中json.Unmarshall的作用为将我们拿到的json(bodyText)进行反序列化成结构体存储到dictResponse当中,然后后面进行输出即可。

案例三:Socks5代理

课程当中贴出了Socks5代理的工作原理

image.png

大致的流程分为三个阶段:协商、建立连接、发送请求

在案例中用到了netCat工具,我们需要下载并配置好环境变量。 这个实验比较麻烦,看来需要恶补计算机网络了,最终实验成功!

image.png