Go语言项目实践笔记
项目一:猜数游戏
项目简介
猜数游戏是一个简单的命令行游戏,计算机随机生成一个0到99的整数,玩家需要猜测这个整数是多少。游戏会根据玩家的猜测给出提示,直到猜中为止。
代码分析
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("Please input your guess")
reader := bufio.NewReader(os.Stdin)
for {
// 读取玩家输入
input, err := reader.ReadString('\n')
if err != nil {
fmt.Println("An error occurred while reading input. Please try again.", err)
continue
}
input = strings.Trim(input, "\r\n")
// 将输入转换成整数
guess, err := strconv.Atoi(input)
if err != nil {
fmt.Println("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.Seed函数设定随机数种子,以当前时间作为种子,确保每次运行游戏随机数都不同。 - 使用
rand.Intn生成一个0到99的随机整数作为猜测目标。 - 使用
bufio.NewReader读取玩家输入的字符串。 - 使用
strings.Trim函数移除输入字符串中的换行符。 - 使用
strconv.Atoi函数将输入字符串转换为整数。 - 根据玩家猜测结果,给出相应的提示,直到猜中为止。
课后实践作业思路
作业要求是简化代码实现,使用fmt的Scan方法,这里我采用fmt.Scanln方法就行,使用Scanln方法可以在接受一个参数的时候以回车结束接收。 只需要在for循环外面声明一个guess参数,之后在每次猜数的时候运行
fmt.Scanln(&guess)
即可
项目二:翻译词典
项目简介
翻译词典是一个命令行工具,可以将英文单词翻译为中文,使用了彩云翻译的API。
代码分析
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
)
type DictResponse struct {
// 省略其他字段
}
type DictRequest struct {
TransType string `json:"trans_type"`
Source string `json:"source"`
UserId string `json:"user_id"`
}
func main() {
if len(os.Args) < 2 {
fmt.Fprintf(os.Stderr, `usage:simpleDict WORD example:simpleDict hello`)
} else {
for i, j := range os.Args {
if i != 0 {
query(j)
}
}
}
}
func query(word string) {
client := &http.Client{}
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)
// 省略设置请求头部分
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 dictResponse DictResponse
err = json.Unmarshal(bodyText, &dictResponse)
if err != nil {
log.Fatal(err)
}
fmt.Println()
fmt.Println(word, "UK:", dictResponse.Dictionary.Prons.En, "US:", dictResponse.Dictionary.Prons.EnUs)
for _, i := range dictResponse.Dictionary.Explanations {
fmt.Println(i)
}
}
代码说明
- 在命令行输入一个英文单词作为参数。
- 使用
http.Client进行网络请求,调用彩云翻译的API进行单词翻译。 - 使用
json.Marshal将请求参数结构体序列化为JSON格式的数据,并使用bytes.NewReader创建请求的数据体。 - 使用
http.NewRequest创建POST请求,并设置请求头部信息。 - 使用
io.ReadAll读取响应的JSON数据,并使用json.Unmarshal将JSON解析为结构体对象。 - 输出翻译结果,包括英式发音和美式发音,以及单词释义。
课后实践作业思路
课后作业要求使用另一个翻译引擎的api实现同样的操作,我这里选择了百度翻译的引擎,但是并未在返回结果里发现音标数据,但是也可以实现其他操作。 思路与使用彩云小译的api大差不差,都是先去网页控制台查看翻译的请求格式
进行翻译之后在控制台找到post请求method的dict请求,然后将其response响应标头复制成curl格式。
之后在转换网站Convert curl to Go (curlconverter.com)将curl转换成go的代码,会自动根据curl格式生成一份可以生成同样请求的go代码。
请求数据序列化marshal成json
将写死的数据抽象成对应的结构体,之后将结构体对象用json包序列化成json,再传到请求里面。
请求之后用变量bodyTest接住得到的结果,再反序列化Unmarshal成我们想要的结果
通过浏览器查看预览格式生成对应结构体
在浏览器查看返回结果的预览结果,之后复制进JSON转Golang Struct - 在线工具 - OKTools网站得到结构对应的结构体,就能在json反序列化的时候用这个结构体接住得到的结果。
项目三:SOCKS5代理
项目简介
SOCKS5代理是一个基于SOCKS5协议的代理服务器,可以用来转发网络请求,实现网络代理功能。
代码分析
package main
import (
"log"
"net"
)
func main() {
// 创建一个TCP server,监听在本地的1080端口
server, err := net.Listen("tcp", "127.0.0.1:1080")
if err != nil {
panic(err)
}
for {
// 接受客户端的连接
client, err := server.Accept()
if err != nil {
log.Print("Accept failed %v", err)
continue
}
// 使用goroutine处理每个连接
go process(client)
}
}
func process(conn net.Conn) {
defer conn.Close()
// 创建一个读取器
reader := bufio.NewReader(conn)
for {
// 读取客户端发送的数据
by, err := reader.ReadByte()
if err != nil {
break
}
// 将数据原样写回客户端,实现简单的回显代理
_, err = conn.Write([]byte{by})
if err != nil {
break
}
}
}
代码说明
- 创建一个TCP服务器,监听在本地的1080端口,等待客户端连接。
- 使用
server.Accept()接受客户端的连接,返回
一个与客户端连接的net.Conn对象。
- 为每个客户端连接启动一个goroutine,使用
process函数处理客户端的请求。 process函数读取客户端发送的数据,并将数据原样写回客户端,实现简单的回显代理功能。
总结
以上三个项目涵盖了Go语言的基础知识和常用库的使用,包括随机数生成、网络请求、JSON数据处理、命令行参数解析、文件读写等。通过这些项目的实践,我们可以更好地理解Go语言的特性和语法,培养编程能力,提高代码质量。同时,这些项目也可以作为基础,进一步拓展和完善,开发更加复杂、功能更加丰富的Go语言应用。