Go语言实践案例之简单字典

2023-09-15 11:04:37

一、程序要实现效果:

在命令行调用程序的时候,可以在命令行的后面查询一个单词,然后会输出单词的音标和注释。

二、思路分析:

  1. 定义一个结构体 DictRequest,用于表示翻译请求的数据结构。其中包含了 TransType(翻译类型)、Source(源语言单词)、UserID(用户ID)等字段。
  2. 定义一个结构体 DictResponse,用于表示翻译响应的数据结构。其中包含了 Rc(返回码)、Wiki(维基百科信息)、Dictionary(词典信息)等字段。
  3. 定义一个函数 query,用于执行翻译请求并获取翻译结果。该函数接受一个参数 word,表示要翻译的单词。
  4. query 函数中,首先创建了一个 HTTP 客户端对象 client,然后构造了一个 DictRequest 对象 request,并将 TransType 设置为 "en2zh",表示将源语言翻译成中文。
  5. 接下来,将 request 对象序列化为 JSON 格式的字节流 buf,并创建一个 bytes.Reader 对象 data 来读取该字节流。
  6. 然后,构造一个 HTTP 请求对象 req,使用 http.NewRequest 函数设置请求的方法为 "POST",URL 为 "api.interpreter.caiyunai.com/v1/dict",并将 data 作为请求的主体数据。
  7. 接着,设置请求头的各项字段,包括连接方式、用户代理、自定义头部字段等。其中,有一些字段的值是通过函数调用来设置的,比如 req.Header.Set("X-Authorization", "token:qgemv4jr1y38jyq6vhvi") 设置了 X-Authorization 头部字段的值为 "token:qgemv4jr1y38jyq6vhvi"。
  8. 最后,通过调用 client.Do(req) 发送请求,并获取到响应对象 resp
  9. 关闭响应对象的 Body 流,并将响应的字节流读取为字符串 bodyText
  10. 使用 json.Unmarshal 函数将 bodyText 解析为 DictResponse 对象 dictResponse
  11. 最后,打印出翻译结果,包括源单词的中英文翻译以及一些解释性的信息。
  12. main 函数中,首先检查命令行参数的数量是否正确,如果不正确则输出使用方法并退出程序。
  13. 如果参数数量正确,则从命令行参数中获取要翻译的单词,并调用 query 函数进行翻译。

三、具体代码

package main

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

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)
	if err != nil {
		log.Fatal(err)
	}
	var data = bytes.NewReader(buf)
	req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data)
	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)
	if err != nil {
		log.Fatal(err)
	}
	if resp.StatusCode != 200 {
		log.Fatal("bad StatusCode:", resp.StatusCode, "body", string(bodyText))
	}
	var dictResponse DictResponse
	err = json.Unmarshal(bodyText, &dictResponse)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(word, "UK:", dictResponse.Dictionary.Prons.En, "US:", dictResponse.Dictionary.Prons.EnUs)
	for _, item := range dictResponse.Dictionary.Explanations {
		fmt.Println(item)
	}
}

func main() {
	if len(os.Args) != 2 {
		fmt.Fprintf(os.Stderr, `usage: simpleDict WORD
example: simpleDict hello
		`)
		os.Exit(1)
	}
	word := os.Args[1]
	query(word)
}

四、实现过程中可能比较有难度的问题

  1. 错误处理:在发送网络请求时,可能会出现连接错误、超时错误、服务器错误等。需要对这些错误进行适当的处理,比如重试、记录日志、返回错误信息等。
  2. 请求头设置:在构造 HTTP 请求时,需要设置各种请求头字段,比如 User-Agent、Cookie、Authorization 等。需要注意各个字段的格式和含义,并确保它们符合 API 的要求。
  3. 编码问题:由于 API 返回的数据可能是 UTF-8 或其他编码方式,需要进行相应的解码操作才能正确地读取其中的内容。同时,在构造请求体时,也需要注意数据的编码和转义问题。
  4. JSON 解析:在解析 JSON 数据时,可能会出现解码错误、类型断言错误等问题。需要使用合适的方法来解析 JSON 数据,比如使用 json.Unmarshal 函数将字节流解析为结构体,或使用 json.Decode 函数将字符串解析为 JSON 对象。
  5. 多语言支持:代码中涉及到了中英文翻译的逻辑,需要根据源语言和目标语言的不同来构造相应的翻译请求。这可能涉及到字符串的处理、字符编码的转换等问题。

五、总结

本篇文章介绍了如何去创建一个简单的命令行字典,其功能为可以将输入的单词翻译成中文或英文。它使用了Interpreter API来与翻译服务进行交互,并通过HTTP请求发送翻译请求并获取响应数据。代码中包含了错误处理、请求头设置、JSON解析等关键步骤,以确保程序的稳定性和正确性。此外,还考虑了多语言支持和编码问题,以应对不同的情况。

如果你对编程有一定的基础,并且对网络编程和JSON解析有一定的了解,那么可以尝试阅读和理解这段代码。通过学习和实践,你可以掌握如何使用Interpreter API来进行翻译服务的开发,以及如何解析和处理JSON数据。这将为你进一步深入学习编程和开发有趣的应用程序提供有价值的经验和技能。

更多推荐

【Vue】轻松理解数据代理

hello,我是小索奇,精心制作的Vue教程持续更新哈,想要学习&巩固&避坑就一起学习叭~Object定义配置方法代码引出数据代理,先上代码,后加解释<!DOCTYPEhtml><html><head><metacharset="UTF-8"/><title>回顾Object.defineproperty方法</tit

Python程序设计实例 | 学生管理数据库系统的开发

本文将通过一个学生管理数据库系统的开发过程来展示如何系统地基于Python实现SQLite数据库编程。以下首先提出数据库系统的基本结构,以及如何通过SQLite逐步达到这些要求并进行常规操作。01、数据表结构该学生管理数据库系统包括4张表:专业表、学生表、课程表和成绩表,用于实现对专业信息、学生信息、课程信息和成绩的综

视频监控系统/安防监控/视频AI智能分析网关:持刀检测算法场景汇总

TSINGSEE青犀AI智能分析网关——持刀检测算法,是一种利用计算机AI分析算法技术来检测和辨别视频中是否存在刀具的算法,用来保障群众安全,维护公共治安,还可以与“人员跌倒”、“人员聚集”、“人员跌倒”等算法结合,制定一体化的安全监管体系,可以应用于各种场景,主要包括以下几个方面:1、公共安全在公共场所,如机场、车站

课程29:.Net Core API限流

🚀前言本文是《.NetCore从零学习搭建权限管理系统》教程专栏的课程(点击链接,跳转到专栏主页,欢迎订阅,持续更新…)专栏介绍:以实战为线索,基于.Net7+REST+Vue、前后端分离,不依赖任何第三方框架,从零一步一步讲解权限管理系统搭建。专栏适用于人群:Web后端开发人员本课程内容:本课程内容:1、API限流

setState是同步还是异步的?

您好,如果喜欢我的文章,可以关注我的公众号「量子前端」,将不定期关注推送前端好文~以下内容针对Reactv18以下版本。前言setState到底是同步还是异步?很多人可能面试都被问到过,就好比这道代码输出题:constructor(props){super(props);this.state={data:'data'}

使用CFimagehost源码搭建免费的PHP图片托管私人图床,无需数据库支持

文章目录1.前言2.CFImagehost网站搭建2.1CFImagehost下载和安装2.2CFImagehost网页测试2.3cpolar的安装和注册3.本地网页发布3.1Cpolar临时数据隧道3.2Cpolar稳定隧道(云端设置)3.3.Cpolar稳定隧道(本地设置)4.公网访问测试5.结语1.前言图片服务器

伦敦银时走势与获利机会

交易时间灵活、资金杠杆充沛是伦敦银交易的主要优势,投资者应该充分利用这个品种的制度优势,结合自己个人的作息时间,在工作、投资与生活三者之间取得平衡的前提下,借助国际白银市场的波动,通过交易逐步实现自己的财富人生。目前贵金属市场上的投资工具已有很多,但的利益应该是交易时间最为灵活的品种之一,因为它每天的交易由亚洲、欧洲和

Nginx是如何支持百万并发的?

通过源码分析Nginx的整体架构,以及进程模型。Nginx是一个免费的,开源的,高性能的HTTP服务器和反向代理。以其高性能,稳定性,丰富的功能,简单的配置和低资源消耗而闻名。Nginx是一个Web服务器,也可以用作负载均衡器和HTTP缓存。很多高知名度的网站都使用Nginx,比如:Netflix,GitHub,Sou

React 全栈体系(十)

第五章React路由三、基本路由使用7.代码-Switch的使用7.1Test/*src/pages/Test/index.jsx*/importReact,{Component}from'react'exportdefaultclassTestextendsComponent{render(){return(<div

1334. 阈值距离内邻居最少的城市

1334.阈值距离内邻居最少的城市原题链接:完成情况:解题思路:参考代码:DijkstraDijkstra_小顶堆Floyd_martix方法原题链接:1334.阈值距离内邻居最少的城市https://leetcode.cn/problems/find-the-city-with-the-smallest-number

HDMI 直通 ILA 调试实验

FPGA教程学习第十四章HDMI直通ILA调试实验文章目录FPGA教程学习前言实验原理程序设计实验过程实验尝试总结TODO前言HDMI输入直通到HDMI输出的显示,完成一个简单的HDMI输入输出检测。实验原理开发板HDMI输出接口芯片使用ADV7511,HDMI输入芯片采用ADV761,可以把输入的数据通过输出直接发送

热文推荐