使用 fmt.Scanf 简化代码实现
在 fmt 标准库中,有三个函数用于扫描输入,分别是 Scanf、Scan 和 Scanln。它们之间存在一些区别:
Scanf:可以识别换行符,需要传入格式化的字符串参数。Scan:可以识别换行符,不需要传入格式化的字符串参数。Scanln:不识别换行符,不需要传入格式化的字符串参数。
这些区别可能会在使用过程中导致问题:
- 在Windows系统中,换行符为
"\r\n"。如果未正确处理换行符,可能导致输入类型与指定类型不匹配,从而得到默认类型的值。 - 当读取的是数字字符时,如果输入的字符长度大于数字长度(例如汉字),但未读取到换行符,会影响后续的输入。
解决这些问题的方法如下:
- 如果使用
fmt.Scanf,需要确保使用"%d\r\n"来处理换行符。或者,可以直接使用fmt.Scan来简化处理。 - 针对错误输入,当出现错误时,需要读取当前行剩余的所有字符,然后跳到下一行继续处理。
核心代码示例:
var guess int
var err error
var buf string
for {
_, err = fmt.Scan(&guess)
if err != nil {
fmt.Println("读取输入时出错,请重试")
fmt.Scan(&buf) // 读取当前行剩余的所有字符
continue
}
// 后续处理逻辑,例如大小比较
}
新增另一种字典翻译引擎
考虑到许多翻译引擎的接口可能需要爬虫技术或者官方API调用,以下以百度翻译为例:
请求体结构如下:
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.PostForm(url,
url.Values{
"q": {word},
"from": {"en"},
"to": {"zh"},
"appid": {appid},
"salt": {salt},
"sign": {sign},
})
if err != nil {
log.Fatal(err)
}
解析响应的代码如下:
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 := ioutil.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, "翻译结果:", response.TransResult[0].Dst)
并发请求两个翻译引擎 可以使用多协程和锁来并发请求两个翻译引擎,可以通过打印时间戳来对照不同引擎的翻译效率:
var wg sync.WaitGroup
var mu sync.Mutex
wg.Add(2)
go func() {
defer wg.Done()
BaiduQuery(word)
mu.Lock()
defer mu.Unlock()
fmt.Println("百度翻译在", time.Now(), "完成")
}()
go func() {
defer wg.Done()
CaiYunQuery(word)
mu.Lock()
defer mu.Unlock()
fmt.Println("彩云翻译在", time.Now(), "完成")
}()
wg.Wait()
请注意,上述代码示例中的 BaiduQuery 和 CaiYunQuery 是代表两个不同翻译引擎的函数。这样,你可以在两个函数内部实现各自的翻译逻辑。同时,通过使用锁,可以确保在并发情况下,时间戳的打印不会交叉。
新增另一种字典翻译引擎 考虑到许多翻译引擎的接口可能需要爬虫技术或者官方API调用,以下以百度翻译为例:
请求体结构如下:
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.PostForm(url,
url.Values{
"q": {word},
"from": {"en"},
"to": {"zh"},
"appid": {appid},
"salt": {salt},
"sign": {sign},
})
if err != nil {
log.Fatal(err)
}
解析响应的代码如下:
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 := ioutil.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, "翻译结果:", response.TransResult[0].Dst)
并发请求两个翻译引擎
可以使用多协程和锁来并发请求两个翻译引擎,可以通过打印时间戳来对照不同引擎的翻译效率:
var wg sync.WaitGroup
var mu sync.Mutex
wg.Add(2)
go func() {
defer wg.Done()
BaiduQuery(word)
mu.Lock()
defer mu.Unlock()
fmt.Println("百度翻译在", time.Now(), "完成")
}()
go func() {
defer wg.Done()
CaiYunQuery(word)
mu.Lock()
defer mu.Unlock()
fmt.Println("彩云翻译在", time.Now(), "完成")
}()
wg.Wait()
请注意,上述代码示例中的 BaiduQuery 和 CaiYunQuery 是代表两个不同翻译引擎的函数。这样,你可以在两个函数内部实现各自的翻译逻辑。同时,通过使用锁,可以确保在并发情况下,时间戳的打印不会交叉。