Go语言实战案例1,2 | 青训营

104 阅读5分钟

笔记的内容

GitHub - wangkechun/go-by-example

以2个go语言实战案例来更深一步去理解go语言的使用:

  • 猜谜游戏
  • 在线词典

------没有scoks5代理----

猜谜游戏

根据输入的数字来判断猜高了还是猜低了,进而得出准确的数字

1. 实现生成随机数

代码如下图:

image.png

引入fmtmath/randtime包,相当于c的头文件,这样我们可以使用其中的函数和工具。我们要调用包内的函数rand.Intn() 。随后,在main函数中定义了一个变量maxNum,并将其初始化为100,我们用它表示生成随机数的最大范围。

math/rand文档对随机数函数的使用是有注意事项的,在使用函数前需要设置一个随机数种子,否则每次都生成相同的随机数序列。一般惯例是在程序启动的时候用启动的时间戳来初始化随机数种子。 rand.Seed()函数用于设置随机数发生器的种子。通过调用time.Now().UnixNano()函数可以获取当前时间的纳秒级表示,从而保证每次运行生成的随机数不同。rand.Intn()函数根据指定的最大值生成一个0到该最大值(不包括最大值)之间的随机整数。这里将生成的随机数赋给变量secretNumber。最后fmt.Println()函数用于在控制台输出信息,这里将显示生成的随机数的值。

2. 读取用户输入

代码如下图:

image.png

maxNum := 100 的作用是将随机数的范围规定在100以内。

secretNumber := rand.Intn(maxNum) 生成一个0到maxNum(不包括maxNum)之间的随机整数。

函数reader := bufio.NewReader(os.Stdin) 的作用是创建一个用于从标准输入读取数据的bufio.Reader

函数input, err := reader.ReadString('\n') 用于读取用户输入的字符串,直到遇到换行符,因此只会读取输入的一行内容。

函数strings.TrimSuffix(input, "\n")函数用于去除输入字符串末尾的换行符。

函数guess, err := strconv.Atoi(input) 将输入的字符串转换为整数,并赋值给变量guess

3. 实现逻辑判断

guess的值与我们生成的随机数进行比较,使用ifelse语句

image.png

4. 实现游戏循环

经过以上的代码,程序大致可以正常工作了,但是玩家只能输入一次猜测,无论猜测是否正确,程序都会退出。为了让游戏可以正常玩下去,我们需要加一个循环。

5. 最终运行效果展示

package main

import (
	"bufio"
	"fmt"
	"math/rand"
	"os"
	"strconv"
	"strings"
	"time"
)

func main() {
	maxNum := 100
	rand.Seed(time.Now().UnixNano())
	secretNumber := rand.Intn(maxNum)
	fmt.Println("The secret number is ", secretNumber)
	fmt.Println("Please input your guess")
	for {
		reader := bufio.NewReader(os.Stdin)
		input, err := reader.ReadString('\n')
		if err != nil {
			fmt.Println("An error occured while reading input. Please try again", err)
			return
		}
		input = strings.Trim(input, "\r\n")

		guess, err := strconv.Atoi(input)
		if err != nil {
			fmt.Println("Invalid input. Please enter an integer value")
			return
		}
		fmt.Println("You guess is", guess)
		if guess > secretNumber {
			fmt.Println("Too large, try again!!")
		} else if guess < secretNumber {
			fmt.Println("Too small, try again!!")
		} else {
			fmt.Println("U are right")
			return
		}
	}
}

在线词典

抓包

根据输入的单词来给出相应的音标和注释,调用第三方的api来查询单词

彩云小译 - 在线翻译 (caiyunapp.com)

1.右键点击检查

image.png

2.选择network,输入文本点击翻译后,选择Request Method中为Postdict选项

image.png

3.PayloadPreview中界面与下图一致则说明操作正确了

image.png

image.png

4.复制代码(选择bash)

image.png

转到此链接:curlconverter.com/#go

粘贴 选择go

image.png

将生成出的代码粘贴到编译器中

生成request body

  1. 定义与输入JSON内容词条一致的结构体
type DictRequest struct {
	TransType string `json:"trans_type"`
	Source    string `json:"source"`
	UserID    string `json:"user_id"`
}
  1. 初始化结构体对象,将对象序列化为JSON字节流
request := DictRequest{TransType: "en2zh", Source: "good"}
	buf, err := json.Marshal(request)
	if err != nil {
		log.Fatal(err)
	}
	var data = bytes.NewReader(buf)

解析response body

获取 与请求报文 相对应的 响应报文的 结构体

链接:oktools.net/json2go

将preview中的json字段粘贴进去,点击转换嵌套

image.png

完善

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
)

type DictRequest struct {
	TransType string `json:"trans_type"`
	Source    string `json:"source"`
	UserID    string `json:"user_id"`
}

type DictResponse struct {
	Rc   int `json:"rc"`
	Wiki struct {
	} `json:"wiki"`
	Dictionary struct {
		Prons struct {
			EnUs string `json:"en-us"`
			En   string `json:"en"`
		} `json:"prons"`
		Explanations []string      `json:"explanations"`
		Synonym      []string      `json:"synonym"`
		Antonym      []string      `json:"antonym"`
		WqxExample   [][]string    `json:"wqx_example"`
		Entry        string        `json:"entry"`
		Type         string        `json:"type"`
		Related      []interface{} `json:"related"`
		Source       string        `json:"source"`
	} `json:"dictionary"`
}

func query(word string) {
	client := &http.Client{}
	//var data = strings.NewReader(`{"trans_type":"en2zh","source":"good"}`)
	request := DictRequest{TransType: "en2zh", Source: word}
	buf, err := json.Marshal(request)
	if err != nil {
		log.Fatal(err)
	}
	var data = bytes.NewReader(buf)

	req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data)
	if err != nil {
		log.Fatal(err)
	}
	req.Header.Set("authority", "api.interpreter.caiyunai.com")
	req.Header.Set("accept", "application/json, text/plain, */*")
	req.Header.Set("accept-language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
	req.Header.Set("app-name", "xy")
	req.Header.Set("content-type", "application/json;charset=UTF-8")
	req.Header.Set("device-id", "426f2bbffd6d824e97f51e6a80ff4f07")
	req.Header.Set("origin", "https://fanyi.caiyunapp.com")
	req.Header.Set("os-type", "web")
	req.Header.Set("os-version", "")
	req.Header.Set("referer", "https://fanyi.caiyunapp.com/")
	req.Header.Set("sec-ch-ua", `"Not/A)Brand";v="99", "Microsoft Edge";v="115", "Chromium";v="115"`)
	req.Header.Set("sec-ch-ua-mobile", "?0")
	req.Header.Set("sec-ch-ua-platform", `"Windows"`)
	req.Header.Set("sec-fetch-dest", "empty")
	req.Header.Set("sec-fetch-mode", "cors")
	req.Header.Set("sec-fetch-site", "cross-site")
	req.Header.Set("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.200")
	req.Header.Set("x-authorization", "token:qgemv4jr1y38jyq6vhvi")
	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))
	}

	//fmt.Printf("%s\n", bodyText)
	var dictResponse DictResponse
	err = json.Unmarshal(bodyText, &dictResponse)
	if err != nil {
		log.Fatal(err)
	}
	//fmt.Printf("dictResponse: %#v\n", dictResponse)
	fmt.Println(word, "UK:", dictResponse.Dictionary.Prons.En, "US:", dictResponse.Dictionary.Prons.EnUs)
	for _, item := range dictResponse.Dictionary.Explanations {
		fmt.Println(item)

	}
}
func main() {
	fmt.Println("请输入要查询的内容:")
	if len(os.Args) != 2 { //
		fmt.Fprintf(os.Stderr, `usage: simpleDict WORD
example: simpleDict hello
`)
		os.Exit(1)
	}
	word := os.Args[1]
	query(word)

	//reader := bufio.NewReader(os.Stdin)
	//word, _ := reader.ReadString('\n')
	//word = strings.Trim(word, "\r\n")

}

1、首先定义了两个结构体类型:DictRequest、DictResponse,用于表示字典请求和响应的数据结构。

2、query函数是主要的执行逻辑,它接受一个单词作为参数,并返回该单词在英文和中文下的翻译结果。

3、在query函数中,首先创建了一个HTTP客户端对象client,用于发送HTTP请求。

4、然后构建了一个DictRequest对象request,其中包含了一些必要的请求参数,如trans_type(翻译类型)、source(源语言)和user_id(用户ID)。

5、接下来将request对象转换为JSON格式的字节数组,并通过bytes.NewReader创建一个可读的字节流对象data,用于后续的HTTP请求数据传输。

6、使用http.NewRequest函数创建了一个HTTP POST请求对象req,指定了请求的URL、请求头信息和请求体数据。

7、最后通过client.Do方法发送HTTP请求,并获取到服务器的响应结果。

8、将响应结果读取到一个字符串变量bodyText中,然后使用json.Unmarshal函数将JSON格式的响应数据解析为一个DictResponse对象。