这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
本节课重点内容
本堂课主要讲述了 Go 语言:
- 如何构建一个简易的猜谜cli游戏
- 如何实现一个简单的词典程序
详细知识点
主要涵括了以下知识点
- Go 语言中,如何获取标准输入
- Go 语言 for循环 continue,break 关键字
- Go 语言 代码生成
- Go 语言 json 序列化与反序列化
实践例子
实现一个简单的猜谜游戏
在 Golang 中可以使用 math/rand 来生成随机数字,为了每次生成不一样的数字,我们应该设置随机数种子。
rand.Seed(time.Now().UnixNano())
secretNum := rand.Intn(100)
fmt.Printf("secretNum is: %v\n", secretNum)
接下来我要尝试捕获用户输入,我们可以通过 bufio.NewReader 来捕获 stdin 输入
reader := bufio.NewReader(os.Stdin)
for {
input, err := reader.ReadString('\n')
if err != nil {
fmt.Printf("err: %v", err)
continue
}
fmt.Printf("input is: %v", input)
}
由于我们读取的参数为 String 我们需使用 strconv.Atoi 将其转换为 Int:
guess, err := strconv.Atoi(input)
if err != nil {
fmt.Printf("Invalid input, please input a integer number")
continue
}
接着需要继续编辑逻辑语句,来告诉用户所输入的参数大于还是小于给出的随机值:
if guess > secretNum {
fmt.Println("your guess is bigger than secret, try again")
} else if guess > secretNum {
fmt.Println("your guess is smaller than secret, try again")
} else {
fmt.Println("correct!")
break
}
从中我们知道了
golang中如何读取 标准输入(stdin) 以及golang生成随机数之前需要传入种子,我们一般将程序运行世的nano时间戳作为种子。
实现一个 CLI词典
我们选择的是 fanyi.caiyunapp.com 作为API,首先进入其官网,通过 Console > Network > Xhr 找到其请求地址, 并将其复制为 Curl
我们可以通过 curlconverter.com 对 curl 进行代码生成:
func main() {
client := &http.Client{}
var data = strings.NewReader(`{"trans_type": "en2zh", "query": "hello"}`)
req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data)
if err != nil {
log.Fatal(err)
}
req.Header.Set("authority", "api.interpreter.caiyunai.com")
req.Header.Set("accept", "application/json, text/plain, */*")
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("app-name", "xy")
req.Header.Set("content-type", "application/json;charset=UTF-8")
req.Header.Set("device-id", "")
req.Header.Set("dnt", "1")
req.Header.Set("origin", "https://fanyi.caiyunapp.com")
req.Header.Set("os-type", "web")
req.Header.Set("os-version", "")
req.Header.Set("referer", "https://fanyi.caiyunapp.com/")
req.Header.Set("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.54")
req.Header.Set("x-authorization", "token:xxxxxxxxxx")
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", bodyText)
}
此时请求后, 便会输出 有关 hello 相关的信息。
除此之外,我们需要生成一个 json, 其包含需要请求的单词:
// 结构体
type DictReq struct {
TransType string `json:"trans_type"`
Source string `json:"source"`
}
func main() {
var req := DictReq{
TransType: "en2zh"
Source: "hellp"
}
json, err = json.Marshal(req)
if err != nil {
log.Fatal(err)
}
fmt.Println(json)
}
生成对应的 json 后即可更简单的请求需要的参数,也可以通过第一个实例项目中的 bufio.NewReader(os.Stdin) 来读取用户的标准输入,给出结果.
除此之外,我们还需要对返回的 json 进行反序列化,这样才能读取我们需要的参数 (如中文)。 虽然我知道 有一个更简单的库可以对 json 中指定node进行读取(gjson), 但还是按照所述内容 通过结构体对其进行解析,我们可以通过 oktools.net/json2go 来对返回结构体进行 代码生成
type DistResp struct {
Rc int `json:"rc"`
Wiki Wiki `json:"wiki"`
Dictionary Dictionary `json:"dictionary"`
}
type Description struct {
Source string `json:"source"`
Target interface{} `json:"target"`
}
type Item struct {
Source string `json:"source"`
Target string `json:"target"`
}
type Wiki struct {
KnownInLaguages int `json:"known_in_laguages"`
Description Description `json:"description"`
ID string `json:"id"`
Item Item `json:"item"`
ImageURL string `json:"image_url"`
IsSubject string `json:"is_subject"`
Sitelink string `json:"sitelink"`
}
type Prons struct {
EnUs string `json:"en-us"`
En string `json:"en"`
}
type Dictionary struct {
Prons Prons `json:"prons"`
Explanations []string `json:"explanations"`
Synonym []string `json:"synonym"`
Antonym []interface{} `json:"antonym"`
WqxExample []WqxExample[]string `json:"wqx_example"`
Entry string `json:"entry"`
Type string `json:"type"`
Related []interface{} `json:"related"`
Source string `json:"source"`
}
func main() {
var dictResp DictResp
err := json.Unmarshal(RespBody, &dictResp)
handleErr(err)
fmt.Println(dictResp)
}
从这个项目,我们学到了 要善于利用代码生成,简化操作。 同时学到了如果对 json 进行反序列化,对map/struct 进行 json 序列化
课后个人总结
Go语言 拥有着丰富的生态,完善的标准库,得益于标准库,很多东西都会在后续的 Go 版本中得到优化,完善。
并且其支持跨平台编译,拥有这远超其他语言的编译速度,也有这完善的 rpc / http 库。因此其很适合开发微服务。
由于其拥有丰富的工具链,包含了 代码格式化 / 编译工具 等,其有着严格的编码规范,所以写出来的代码 风格类似,易于团队协作。
Golang 有着完善的 自动CG功能,开发着不用时刻关注垃圾回收