这是我参与「第五届青训营」伴学笔记创作活动的第 1 天
今日内容
学习完了青训营课程 后端入门 - Go 语言原理与实践 中的 走进 Go 语言基础语言 和 Go 语言的实战案例 之后,尝试完成这两节课的课后作业。
作业内容:
- 修改第一个例子猜谜游戏里面的最终代码,使用 fmt.Scanf 来简化代码实现
- 修改第二个例子命令行字典里面的最终代码,增加另一种翻译引擎的支持
- 在上一步骤的基础上,修改代码实现并行请求两个翻译引擎来提高响应速度
作业 1
fmt.Scanf 的使用方法为
func Scanf(format string, a ...any) (n int, err error)
fmt package - fmt - Go Packages
官方描述:
Scanf 扫描从标准输入读取的文本,将连续的空格分隔值存储到由格式确定的连续参数中。 它返回成功扫描的项目数。 如果它小于参数的数量,err 将报告原因。 输入中的换行符必须与格式中的换行符匹配。 一个例外:动词 %c 总是扫描输入中的下一个符文,即使它是空格(或制表符等)或换行符。
简单的使用方法为:
package main
import "fmt"
func main() {
var a int
fmt.Printf("input: ")
_, err := fmt.Scanf("%d", &a)
if err != nil {
fmt.Printf("error occurred: %s\n", err.Error())
return
}
fmt.Printf("a is %d\n", a)
}
两个测试样例结果如下
接下来可以对这个函数封装一下以便让代码更加清晰明了
func input(format string, a ...interface{}) {
for {
_, err := fmt.Scanf(format, a...)
if err != nil {
fmt.Printf("error occurred: %s\n", err.Error())
continue
}
break
}
}
最终代码如下:
package main
import (
"fmt"
"math/rand"
"time"
)
func input(format string, a ...interface{}) {
for {
_, err := fmt.Scanf(format, a...)
if err != nil {
fmt.Printf("error occurred: %s\n", err.Error())
continue
}
break
}
}
func main() {
maxNum := 100
rand.Seed(time.Now().UnixNano())
secretNumber := rand.Intn(maxNum)
// fmt.Println("The secret number is ", secretNumber)
fmt.Printf("Please input your guess: ")
for {
var guess int
input("%d", &guess)
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
}
}
}
最终结果如下:
作业 2
我尝试了一会儿,发现基本上的翻译 api 都是需要 token 的,彩云这个好像是因为 token 不会过期所以代码一直能跑,去各大公司注册拿 api 比较麻烦,就暂时不做了。基本操作都和老师上课说的差不多,如果去各大公司注册应该也会有相应的教程。
作业 3
并行请求,其实就是每个请求都作为一个 goroutine 去执行,主要代码如下
func main() {
var word1, word2 string
fmt.Printf("input two words: ")
input("%s %s", &word1, &word2)
go query(word1)
go query(word2)
}
其实问题很明显,主线程在协程结束之前就结束了,需要有等待操作,如果担心在输出时会发生打印错乱的情况,可以在打印的时候加锁。
var wg = sync.WaitGroup{}
func query() {
defer wg.Done()
...
}
func main() {
var word1, word2 string
fmt.Printf("input two words: ")
input("%s %s", &word1, &word2)
wg.Add(2)
go query(word1)
go query(word2)
wg.Wait()
}