在第一次完成学习后有三个小作业,本文章旨在完成作业并记录下这一过程
1、使用fmt.Scanf来简化代码实现
Scanf,Scan,Scanln三者的区别
Scanf、Scan 和 Scanln 都是 Go 语言 fmt 标准库中的扫描函数,它们之间有以下区别:
- Scan 会在换行符(包括 '\n' 和 '\r')处停止扫描,但不会将其读取,因此换行符会留在输入缓冲区中。
- Scanln 会识别换行符,读取并丢弃它们,因此不会将换行符留在输入缓冲区中。
- Scanf 需要传入一个格式化的字符串参数,以指定如何解析输入。
在使用这些函数时,可能会遇到以下问题:
- 换行符处理:在 Windows 系统中,换行符通常是 "\r\n"。如果不注意处理它们,可能会导致输入格式不匹配,因为换行符也会被读取。这可能导致值与类型的默认值不匹配。
- 错误输入处理:如果输入中包含比预期的数据长度更长的字符,如汉字,但没有读取到换行符,这也可能导致输入格式错误。
为了处理这些问题,可以采取以下方法:
- 使用 fmt.Scanf 时,确保格式化字符串中包含换行符,例如 "%d\r\n",以便正确处理 Windows 换行符。
- 对于错误输入,当发生扫描错误时,可以读取并丢弃当前行的剩余字符,直到下一行。这样可以确保输入不会被错误字符影响。
核心代码
var guess int
var err error
var buf string
for {
_, err = fmt.Scan(&guess)
if err != nil {
fmt.Println("An error occured while reading input. Please try again")
fmt.Scan(&buf) //读取这一行剩下的所有字符
continue
}
//后面就是比大小环节
}
2、对于字典,增加另一种翻译引擎
鉴于许多在线翻译引擎的接口可能较为复杂且不太容易直接调用,通常需要一些爬虫或数据采集技术来从它们的网站上抓取数据。但为了更便捷、稳定、合法地进行翻译操作,可以考虑向官方申请 API 访问权限。在这里,以百度翻译为例,百度提供了官方的翻译 API,您可以申请并获得访问权限,以便通过正式的途径获取翻译数据。
请求体结构
百度翻译api接口采取的不是json解析,而是url编码,因此需要有一些改变,其中请求所用的结构体如下
请求体结构
q=查询的单词
from=源语言
to=目标语言
appid=个人id,去控制台查看
salt=任意长度字符串
sign=md5(appid+word+salt+key)
结构体构建
var url = "https://fanyi-api.baidu.com/api/trans/vip/translate"
sign := fmt.Sprintf("%x", md5.Sum([]byte(appid+word+salt+key)))
res, err := http.Post(url,
"application/x-www-form-urlencoded",
strings.NewReader(
"q="+word+
"&from=en&to=zh&appid="+appid+
"&salt="+salt+
"&sign="+sign),
)
if err != nil {
log.Fatal(err)
}
解析响应
go
复制代码
type Response struct {
From string `json:"from"`
To string `json:"to"`
TransResult []struct {
Src string `json:"src"`
Dst string `json:"dst"`
} `json:"trans_result"`
}
content, err := io.ReadAll(res.Body)
if err != nil {
log.Fatal(err)
}
var Response Response
err = json.Unmarshal(content, &Response)
if err != nil {
log.Fatal(err)
}
fmt.Println(word, "translate:", Response.TransResult[0].Dst)
3、并行请求两个翻译引擎
开个多协程,用锁来协同返回。
scss
复制代码
var wg sync.WaitGroup
wg.Add(2)
go func() {
BaiduQuery(word)
wg.Done()
}()
go func() {
CaiYunQuery(word)
wg.Done()
}()
wg.Wait()
总的来说,完成这三个作业不仅加深了我的 Go 语言编程知识,还提供了处理输入、与外部服务通信以及并发编程的宝贵经验。这些都是构建实际应用程序时必不可少的技能,我感到收获颇丰。同时,我也认识到了编程中的一些常见挑战,如输入验证和错误处理,这些挑战在实际项目中经常会遇到,需要谨慎处理。