[用go语言实现在线词典|青训营笔记]

157 阅读4分钟

[用go语言实现在线词典|青训营笔记]

这是我参与[第五届青训营]笔记创作活动的第1天。这里实现一下课程中的实战案例2:在线词典

实现效果

青训营笔记.md14424.6518033.png

实现的原理即为调用第三方的翻译api。进入fanyi.caiyunapp.com/网站后,随便输入一个单词点击“翻译”,即为请求;显示释译结果,即为响应。

实现过程

  刚刚是在网站上进行翻译,现在我们要把翻译“搬”到自己的编译器或者命令行中。这里可以用一个工具(https://curlconverter.com/go/),它可以根据curl请求,直接生成访问api,实现相关服务的代码。

curl:用来请求 Web 服务器的工具,它的名字就是客户端(client)的 URL 工具的意思

1.复制工具生成的代码

打开检查面板,找到检查面板中名为dict的POST请求并复制其curl 青训营笔记.md17285.5915511.png

再粘贴到工具命令行中,选择go语言,可以看到面板直接生成了实现翻译服务的代码👇。 青训营笔记.md17414.0324379.png

2.修改代码

对生成的代码做出以下修改,创建了请求信息的结构体,同时实现了请求信息的类型转换,后面马上就会讲做出的修改具体是什么意思
笔记day1.md66963.7199908.png

刚刚我们修改的内容实现了翻译信息结构体的序列化 
调用json.marshal(变量),即把变量中的数据序列化 笔记day1.md67095.4372367.png

可以理解为,把存储翻译信息的变量序列化为byte数组,以方便数据传输

既然把变量数据传输上去需要进行序列化,那传输回来的数据要储存到本地就要进行反序列化。

3.创建响应结构体

之前已经写了请求结构体,我们再来创建一个响应结构体来作本地变量,用来存储翻译结果,这里我们又可以运用工具<JSON转Golang Struct - 在线工具 - OKTools>,我们先复制浏览器页面响应翻译的json内容👇 笔记day1.md64654.3934919.png

再输入到json栏中,选择嵌套转换
笔记day1.md64754.9710709.png

可以看到工具又帮我们生成了go语言的结构体,自行复制进工程即可。

4.反序列化

自行创建一个刚刚生成的结构体变量,把json翻译结果的byte数组反序列化,再储存结果信息到变量中。最后输出即可
笔记day1.md67345.0995543.png

完整代码

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)

type DictRequest struct { //请求结构体
	TransType string `json:"trans_type"`
	Source    string `json:"source"`
	UserID    string `json:"user_id"`
}

type DictResponse struct { //响应结构体
	Rc   int `json:"rc"`
	Wiki struct {
		KnownInLaguages int `json:"known_in_laguages"`
		Description     struct {
			Source string      `json:"source"`
			Target interface{} `json:"target"`
		} `json:"description"`
		ID   string `json:"id"`
		Item struct {
			Source string `json:"source"`
			Target string `json:"target"`
		} `json:"item"`
		ImageURL  string `json:"image_url"`
		IsSubject string `json:"is_subject"`
		Sitelink  string `json:"sitelink"`
	} `json:"wiki"`
	Dictionary struct {
		Prons struct {
			EnUs string `json:"en-us"`
			En   string `json:"en"`
		} `json:"prons"`
		Explanations []string      `json:"explanations"`
		Synonym      []string      `json:"synonym"`
		Antonym      []string      `json:"antonym"`
		WqxExample   [][]string    `json:"wqx_example"`
		Entry        string        `json:"entry"`
		Type         string        `json:"type"`
		Related      []interface{} `json:"related"`
		Source       string        `json:"source"`
	} `json:"dictionary"`
}

func query(word string) {
	client := &http.Client{}
	request := DictRequest{TransType: "en2zh", Source: word} //创建自定义的请求结构体
	buf, err := json.Marshal(request)//序列化结构体,转型为byte数组
	if err != nil {
		log.Fatal(err)
	}
	var data = bytes.NewReader(buf)//将byte数组转换为流
	req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data) //创建请求,参数为请求方法、url、流
	if err != nil {
		log.Fatal(err)
	}
	req.Header.Set("Connection", "keep-alive")
	req.Header.Set("DNT", "1")
	req.Header.Set("os-version", "")
	req.Header.Set("sec-ch-ua-mobile", "?0")
	req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36")
	req.Header.Set("app-name", "xy")
	req.Header.Set("Content-Type", "application/json;charset=UTF-8")
	req.Header.Set("Accept", "application/json, text/plain, */*")
	req.Header.Set("device-id", "")
	req.Header.Set("os-type", "web")
	req.Header.Set("X-Authorization", "token:qgemv4jr1y38jyq6vhvi")
	req.Header.Set("Origin", "https://fanyi.caiyunapp.com")
	req.Header.Set("Sec-Fetch-Site", "cross-site")
	req.Header.Set("Sec-Fetch-Mode", "cors")
	req.Header.Set("Sec-Fetch-Dest", "empty")
	req.Header.Set("Referer", "https://fanyi.caiyunapp.com/")
	req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9")
	req.Header.Set("Cookie", "_ym_uid=16456948721020430059; _ym_d=1645694872")
	resp, err := client.Do(req) //发请求
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close() //关闭流
	bodyText, err := ioutil.ReadAll(resp.Body) //把该流,类型转换为byte数组,此byte数组内容为JSON字符串
	if err != nil {
		log.Fatal(err)
	}
	//---------------------------------------------------------↑工具生成的代码,自行添加请求结构体,并序列化

	var dictResponse DictResponse //创建响应结构体变量
	err = json.Unmarshal(bodyText, &dictResponse) //反序列化,将json中的数据写入结构体
	if err != nil {
		log.Fatal(err)
	}

	//只输出需要的东西,需要的东西可以在 浏览器的响应预览中查看字段
	pronsUS := dictResponse.Dictionary.Prons.EnUs
	pronsEn := dictResponse.Dictionary.Prons.En

	if len(pronsEn) == 0 {
		println("没有查找到该单词哦T-T")
		return
	}
	fmt.Println(word, "---------", "UK:", pronsEn, "US:", pronsUS) //输出英/美音标
	for _, item := range dictResponse.Dictionary.Explanations {
		fmt.Println(item)
	} //循环输出中文释意
}

func main() {
	print("请输入一个单词:")
	var word string
	fmt.Scanln(&word)
	query(word)
}

思考:什么是序列化,为什么要序列化?

序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据, 要想将对象传输于网络必须进行流化!在对象流进行读写操作时会引发一些问题,而序列化机制正是用来解决这些问题的

新人小白,完成作业,有哪里写的不对的地方还请指出!!一起学习