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

89 阅读5分钟

课后作业

1. 修改第一个例子猜谜游戏里面的最终代码,使用 fmt.Scanf 来简化代码实现

程序执行时通常会自动打开三个标准文件:

  • 标准输入文件(stdin),通常对应终端的键盘;
  • 标准输出文件(stdout)和标准错误输出文件(stderr),这两个文件都对应终端的屏幕。

进程将从标准输入文件中得到输入数据,将正常输出数据输出到标准输出文件,而将错误信息送到标准错误文件中

但是读取输入的值最简单的办法是使用 fmt 包提供的 Scan 和 Sscan 开头的函数。

fmt.Scanln()的使用先声明需要的变量

比如

var name string

fmt.Scanln(&name)

当程序执行到 fmt.Scanl(&name), 程序会停止这里, 等待用户输入, 并回车

此时name就被赋值了,后续可直接输出

fmt.Scanf()的使用fmt.Scanf()可以按指定的格式输入

输入值,使用空格隔开

比如:

// 需求: 从控制台接收用户信息【姓名, 年龄, 薪水, 是否拿到offer】

var name string
var age byte
var salary float32
var isOffer bool

fmt.Println("请输入您的姓名, 年龄,薪水,是否拿到offer")
fmt.Scanf("%s %d %f %t", &name, &age, &salary, &isOffer)

scanf可以实现输入同时多个值

更新代码如下:

var guess int
for {
//使用scan简化
fmt.Scanf("%v", &guess)。。。

在死循环外定义guess整数变量,死循环内做用户键盘输入

测试如下:

image.png

2.修改第二个例子命令行词典里面的最终代码,增加另一种翻译引擎的支持

更改翻译的api为谷歌翻译 :

先去谷歌翻译网站复制CURL(bash)格式的,然后到Convert curl commands to code (curlconverter.com)这个网站去把curl转成go语言,再粘贴到query函数里

然后主要建立负载和预览的结构体:

这里要把负载信息转成json格式,把负荷的信息(json格式)转成goland的结构体,在这个网站JSON转Golang Struct - 在线工具 - OKTools可以实现,对于有嵌套内容较多的,就选择转换-嵌套,复制即可。

在query方法里把负载的json格式初始化,再序列化为byte数组,再用bytes的只读流读取
在输出那里,把输出的json格式反序列化为数组,再转为字符串选择性输出

package main

import (
"net/http"
"os"
)

import (
"bytes"
"crypto/tls"
"encoding/json"
"fmt"
"io"
"log"
)

type DictResp struct {
Code int json:"code"
Msg string json:"msg"
}

// DictReq 请求数据结构体
type DictReq struct {
Orig string json:"orig"
Sl string json:"sl"
Tl string json:"tl"
Key string json:"key"
Orig2 string json:"orig2"
Sigk string json:"sigk"
}

func query(word string) {
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}

//把json变量初始化,再序列化成buf数组(byte数组),再变成只读的流
request := DictReq{
Orig: word,
Sl: "auto",
Tl: "zh-CN",
Key: "GL13899-8-8-1-424516",
Orig2: word,
Sigk: "e066DJzKtxiVDF4CDdKzqOwvlymznRJb8v+AIBNS/SqclJ8hSyB4o0OzWhbMKW3UKP9ksCQfH89RNKrB0PUE0U0",
}
buffer, err := json.Marshal(request)
if err != nil {
log.Fatal(err)
}
var data = bytes.NewReader(buffer)
req, err := http.NewRequest("POST", "translate.gl.xcxbq.cn/index/langu…", data)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Accept", "/")
req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
req.Header.Set("Connection", "keep-alive")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
req.Header.Set("Cookie", "PHPSESSID=e52449b356477da32629a7159977c98d; __51uvsct__Jy5H9A2z9xpQdJ5R=1; __51vcke__Jy5H9A2z9xpQdJ5R=ac20e802-6efd-5fa3-bd3c-aa8aca7f48b5; __51vuft__Jy5H9A2z9xpQdJ5R=1684147282215; Hm_lvt_618ec6787d90a03e102e14d27b4b55b2=1684147282; Hm_lvt_36a25627026af439e86de5487776b460=1684147283; __vtins__Jy5H9A2z9xpQdJ5R=%7B%22sid%22%3A%20%2286a432fb-4068-537a-9309-dc8db29ec3b9%22%2C%20%22vd%22%3A%203%2C%20%22stt%22%3A%2070442%2C%20%22dr%22%3A%208160%2C%20%22expires%22%3A%201684149152650%2C%20%22ct%22%3A%201684147352650%7D; Hm_lpvt_618ec6787d90a03e102e14d27b4b55b2=1684147353; Hm_lpvt_36a25627026af439e86de5487776b460=1684147353")
req.Header.Set("Origin", "translate.gl.xcxbq.cn")
req.Header.Set("Referer", "translate.gl.xcxbq.cn/index?q=awa…")
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35")
req.Header.Set("X-Requested-With", "XMLHttpRequest")
//真正发请求
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
if resp.StatusCode != 200 {
//出错时候返回状态码和报文,方便我们找到问题
//不加这个检测的话,出错了反序列化返回的就是一个空结构,无法知道问题所在
fmt.Println("错误状态码:", resp.StatusCode, "body", string(bodyText))
}

//fmt.Printf("%s\n", bodyText)
//打印body先把json格式反序列化到这个response结构体当中,此时结构体为字符串,方便输出指定内容
var dictResp DictResp
err = json.Unmarshal(bodyText, &dictResp)
if err != nil {
log.Fatal(err)
}
fmt.Println(request.Orig)
fmt.Println("进入删除宿舍")
fmt.Println(dictResp.Msg)
}
func main() {
if len(os.Args) != 2 {
fmt.Println(os.Stderr, "输入错误")
os.Exit(1)
}
word := os.Args[1]
query(word)
}

测试如下:

image.png 能获取的到响应的code这些,但是获取message是被谷歌禁止的

3.在上一步骤的基础上,修改代码实现并行请求两个翻译引擎来提高响应速度