一、猜谜游戏的另一种写法
1、修改第一个例子猜谜游戏里面的最终代码,使用fmt.Scanf来简化代码的实现。
请注意,在使用 fmt.Scanf 读取输入时,我们在格式字符串末尾加上 \n,以便读取并忽略输入中的换行符,确保每次读取都是从新的一行开始。
package main
//猜谜游戏
import (
"fmt"
"math/rand"
"time"
)
func main() {
maxNum := 100
rand.Seed(time.Now().UnixNano()) //用时间戳来初始化随机数种子
secretNumber := rand.Intn(maxNum)
fmt.Println("请猜一个1到100之间的整数:")
var guess int
for {
_, err := fmt.Scanf("%d\n", &guess)
if err != nil {
fmt.Println("无效的输入,请重新输入整数:")
continue
}
fmt.Println("You guess is", guess)
if guess > secretNumber {
fmt.Println("您的猜测大于该数字,请重试")
} else if guess < secretNumber {
fmt.Println("您的猜测小于该数字,请重试")
} else {
fmt.Println("猜测正确,你赢了")
break
}
}
}
二、在线词典的2种翻译引擎写法
2、修改第二个例子命令行词典里面的最终代码,增加另一种翻译引擎的支持。
跟第一种使用了差不多的写法,流程下来都是那一套。但是由于第二个接口的加密,所以暂时无法返回内容,咱没法解决这个问题。
package main
import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"strings"
)
type DictRequest struct {
TransType string
Source string
UserID string
}
type DictResponse struct {
//此处省略
}
type DictResponse2 struct {
//此处省略
}
func query(word string) {
url := "https://api.interpreter.caiyunai.com/v1/dict"
method := "POST"
payload := strings.NewReader(`{"trans_type":"en2zh","source":"` + word + `"}`)
client := &http.Client{}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
return
}
//此处省略
req.Header.Add()
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)
}
if resp.StatusCode != 200 {
log.Fatal("bad StatusCode:", resp.StatusCode, "body", string(bodyText))
}
var dictResponse DictResponse
err = json.Unmarshal(bodyText, &dictResponse)
if err != nil {
log.Fatal(err)
}
fmt.Println(word, "UK:", dictResponse.Dictionary.Prons.En, "US:", dictResponse.Dictionary.Prons.EnUs)
for _, item := range dictResponse.Dictionary.Explanations {
fmt.Println(item)
}
}
func query_sougo(word string) {
url := "https://fanyi.sogou.com/api/transpc/text/result"
method := "POST"
payload := strings.NewReader(`{"from":"auto","to":"zh-CHS","text":"` + word + `","client":"pc","fr":"browser_pc","needQc":1,"s":"dccdc10851a31d187d79396e3467e22e","uuid":"a22e67a0-61f5-4844-a668-1cf0f401fdee","exchange":false}`)
client := &http.Client{}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
return
}
//此处省略
req.Header.Add()
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
var dictResponse DictResponse2
err = json.Unmarshal(body, &dictResponse)
if err != nil {
log.Fatal(err)
}
fmt.Println(word, "sougo:", dictResponse.Data.Gaokao.ExamFreqInfo)
for _, item := range dictResponse.Data.Gaokao.ExamFreqInfo {
fmt.Println(item)
}
}
func main() {
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, `usage: simpleDict WORD
example: simpleDict hello
`)
os.Exit(1)
}
word := os.Args[1]
//var word = "hello"
query(word)
query_sougo(word)
}
三、命令行在线词典(并行版)
3、在上一步骤的基础上,修改代码实现并行请求两个翻译引擎来提高响应速度。
在main函数中使用wg.Add(2)设置等待的Goroutine数量为2,表示需要等待两个Goroutine(即两次请求)完成。
通过mutex.Lock()获取互斥锁,保证对dataMessage变量的安全访问。如果dataMessage为空(即第一个返回的请求),则将响应内容存入其中。最后,通过mutex.Unlock()释放锁,并调用wg.Done()表示该Goroutine已完成。
最后,在主函数中使用wg.Wait()等待所有Goroutine完成,然后打印dataMessage的内容。
package main
import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"strings"
"sync"
)
var (
dataMessage string
mutex sync.Mutex
wg sync.WaitGroup
)
type DictResponse struct {
//此处省略
}
type DictResponse2 struct {
//此处省略
}
func query1(word string) {
url := "https://api.interpreter.caiyunai.com/v1/dict"
method := "POST"
payload := strings.NewReader(`{"trans_type":"en2zh","source":"` + word + `"}`)
client := &http.Client{}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
return
}
//此处省略
req.Header.Add()
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)
}
if resp.StatusCode != 200 {
log.Fatal("bad StatusCode:", resp.StatusCode, "body", string(bodyText))
}
var dictResponse DictResponse
err = json.Unmarshal(bodyText, &dictResponse)
if err != nil {
log.Fatal(err)
}
mutex.Lock()
if dataMessage == "" {
dataMessage = word + "\t彩云:\t" + dictResponse.Dictionary.Explanations[0]
}
mutex.Unlock()
wg.Done() // 每个Goroutine完成时释放锁和WaitGroup计数
}
func query_sougo1(word string) {
url := "https://fanyi.sogou.com/api/transpc/text/result"
method := "POST"
payload := strings.NewReader(`{"from":"auto","to":"zh-CHS","text":"` + word + `","client":"pc","fr":"browser_pc","needQc":1,"s":"dccdc10851a31d187d79396e3467e22e","uuid":"a22e67a0-61f5-4844-a668-1cf0f401fdee","exchange":false}`)
client := &http.Client{}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
return
}
//此处省略
req.Header.Add()
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
var dictResponse DictResponse2
err = json.Unmarshal(body, &dictResponse)
if err != nil {
log.Fatal(err)
}
mutex.Lock()
if dataMessage == "" {
dataMessage = word + "搜狗:" + dictResponse.Data.Gaokao.ExamFreqInfo[0].Chinese
}
mutex.Unlock()
wg.Done() // 每个Goroutine完成时释放锁和WaitGroup计数
}
func main() {
wg.Add(2) // 设置等待的Goroutine数量为2
var word = "hello"
go query1(word)
go query_sougo1(word)
wg.Wait() // 等待所有Goroutine完成
fmt.Println(dataMessage)
}