GO语言工程实践课后作业 | 青训营

50 阅读3分钟

在第一次完成学习后有三个小作业,本文章旨在完成作业并记录下这一过程

1、使用fmt.Scanf来简化代码实现

Scanf,Scan,Scanln三者的区别

Scanf、Scan 和 Scanln 都是 Go 语言 fmt 标准库中的扫描函数,它们之间有以下区别:

  1. Scan 会在换行符(包括 '\n' 和 '\r')处停止扫描,但不会将其读取,因此换行符会留在输入缓冲区中。
  2. Scanln 会识别换行符,读取并丢弃它们,因此不会将换行符留在输入缓冲区中。
  3. Scanf 需要传入一个格式化的字符串参数,以指定如何解析输入。

在使用这些函数时,可能会遇到以下问题:

  1. 换行符处理:在 Windows 系统中,换行符通常是 "\r\n"。如果不注意处理它们,可能会导致输入格式不匹配,因为换行符也会被读取。这可能导致值与类型的默认值不匹配。
  2. 错误输入处理:如果输入中包含比预期的数据长度更长的字符,如汉字,但没有读取到换行符,这也可能导致输入格式错误。

为了处理这些问题,可以采取以下方法:

  1. 使用 fmt.Scanf 时,确保格式化字符串中包含换行符,例如 "%d\r\n",以便正确处理 Windows 换行符。
  2. 对于错误输入,当发生扫描错误时,可以读取并丢弃当前行的剩余字符,直到下一行。这样可以确保输入不会被错误字符影响。

核心代码

    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 语言编程知识,还提供了处理输入、与外部服务通信以及并发编程的宝贵经验。这些都是构建实际应用程序时必不可少的技能,我感到收获颇丰。同时,我也认识到了编程中的一些常见挑战,如输入验证和错误处理,这些挑战在实际项目中经常会遇到,需要谨慎处理。