Go语言上手-简单基础-作业复盘 | 青训营笔记

191 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第一篇笔记

课后作业:

  1. 修改第一个例子猜谜游戏里面的最终代码,使用 fmt.Scanf 来简化代码实现
  1. 修改第二个例子命令行词典里面的最终代码,增加另一种翻译引擎的支持
  1. 在上一步骤的基础上,修改代码实现并行请求两个翻译引擎来提高响应速度

Assignment#1

直接修改读取的代码即可,这里要注意的是fmt.Scanf()不会把最后的回车\n给舍弃,下一次就会读入该回车而出错了(与C语言中的scanf一致,C中常用getchar读掉回车),这里我们在scanf的格式字符串的末尾加个\n就好了

代码

package main

import (
   "fmt"
   "math/rand"
   "time"
)

func main() {
   maxNum := 100
   rand.Seed(time.Now().UnixNano())
   secretNumber := rand.Intn(maxNum)
   fmt.Println("Please input your guess")

   for {
      var guess int
      _, err := fmt.Scanf("%d\n", &guess)
      if err != nil {
         fmt.Println("Invalid input. Please enter an integer value")
         continue
      }
      fmt.Println("Your guess45 is", guess)

      if guess > secretNumber {
         fmt.Println("Your guess is bigger than the secret number. Please try again")
      } else if guess < secretNumber {
         fmt.Println("Your guess is smaller than the secret number. Please try again")
      } else {
         fmt.Println("Correct, you Legend!")
         break
      }
   }
}

执行情况

image.png

Assignment#2

大致做法就是,打开一个翻译网站(推荐用Chrome打开)我这里以有道智云AI翻译为例,右键-检查-NETWORK,然后在网站的翻译框内输入单词并翻译,就可以在network里看到出现了个request(不同翻译网站不一样),点击我们看到这个request的相关信息

image.png request的Header里注明了请求的头部,我们可以看到里面的Request URLRequest Method为POST方法,并且Status Code为200,同时我们再打开preview看下是否返回的response是不是翻译的结果,是的话那么我们的请求就找对了

image.png 如果要自己写一个请求并且返回的代码来说还是比较复杂的,这里我们可以用到一个网站Convert curl commands to Code,我们只需要复制刚刚找到的request的curl命令就可以通过这个网站转换成对应的代码,支持多种语言

image.png 这里我是windows平台所以复制的bash格式的curl,复制完成后,运行代码我们发现返回的结果是json格式的,我们看起来非常别扭,我们可以通过另外一个网站json2go将json格式转换成Go的struct,注意这里的复制的是Response的原json格式而不是preview,修改后的完整代码如下(包括彩云)

code 代码详见github仓库

执行结果

image.png

我一开始用的是火山翻译,但是一直出现http request的statuscode是200的情况下,response.body为0的不合理情况,因为个人计网水平不足,日后来补坑

Assignment#3

通过Goroutine,channels和sync.WaitGroup实现并发翻译,提高速度

这里只解释下为什么用到channel,如果单纯用goroutine,两个翻译并发进行,输出的结果就是混合的,可能彩云翻译了一点,有道又翻译了一点,通过添加channels是两个goroutine实现通信,我在有道翻译函数执行前通过接收channel实现阻塞,等到channel发送数据过来才执行,而channel的发送操作我放在了彩云翻译函数的后面,这里传的数据是什么并不重要,可以用空struct,节省内存

main代码

func main() {
   if len(os.Args) != 2 {
      fmt.Fprintf(os.Stdout, `usage: simpleDict WORD example:
simpleDict hello`)
      os.Exit(1)
   }
   word := os.Args[1]
   var wg sync.WaitGroup
   wg.Add(2)
   ch := make(chan struct{})
   go func() {
      defer wg.Done()
      query_caiyun(word)
      ch <- struct{}{}
   }()
   go func() {
      defer wg.Done()
      <-ch
      query_Youdao(word)
   }()
   wg.Wait()
}