课后作业
- 修改第一个例子猜谜游戏里面的最终代码,使用 fmt.Scanf 来简化代码实现。
- 修改第二个例子命令行词典里面的最终代码,增加另一种翻译引擎的支持。
- 在上一步骤的基础上,修改代码实现并行请求两个翻译引擎来提高响应速度。
作业仓库地址:git@github.com:wangkechun/go-by-example.git
习题解答
第一题
函数原型 fmt.Scanf 可以以类 C 的方式读入输入的数据,我们此处需要一个 int 来表示我们猜测的数字,因此我们可以写出:
func main() {
maxNum := 100
rand.New(rand.NewSource(time.Now().UnixNano()))
secretNumber := rand.Intn(maxNum)
fmt.Print("Please input your guess: ")
for {
var guess int
_, err := fmt.Scanf("%d\r\n", &guess)
if err != nil {
fmt.Print("Invalid input. Please enter an integer value:")
continue
}
fmt.Println("You guess 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
}
}
}
其中我们替换了随机数生成的函数,因为原代码的 rand 函数已被弃用。
第二题
我们随意找到一个网站,例如 Cambridge Dictionary,我们通过视频的方式获取对应的信息,然后编写出相关代码:
这个地方首先是通过生成器来自动生成了请求过程和结构模型的代码。笔者特地挑选了一个不含接口签名的翻译网站进行测试(若有接口签名,其用意已经不符合青训营习题初衷)。另一方面,我们省略了不重要的代码片段。
func query2(word string) {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://dictionary.cambridge.org/zhs/auth/info, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("AMP-Same-Origin", "true")
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
var res DicStruct
if err := json.Unmarshal(bodyText, &res); err != nil {
log.Fatal("Error for unmarshalling json result")
return
}
fmt.Println(res.TranslatePanelDefaultEntry.DatasetText, ": ", res.TranslatePanelDefaultEntry.EntryLeft)
}
第三题
根据要求,我们并行两个程序即可。注意不可开两个 go,否则主程序会直接终止的。这是因为两个go均作为非前台线程运行,当main运行结束后两个go所在的goroutine会直接停止。
go query(word)
query2(word)
完整代码可以在ByteDanceCampusPractice获取。