go 语言基础语法与小实践
-
第一部分主要为了解go语言的一些基本语法,在这里就不多赘述,各种样例在仓库的 example 文件夹中。
这里指路一个适合基础语法入门的教程网站 Go 语言教程 | 菜鸟教程
-
第二部分为三个小实践
- 猜数字游戏
maxNum := 100 rand.Seed(time.Now().UnixNano()) secretNumber := rand.Intn(maxNum) // fmt.Println("The secret number is ", secretNumber) fmt.Println("Please input your guess") reader := bufio.NewReader(os.Stdin) for { input, err := reader.ReadString('\n') if err != nil { fmt.Println("An error occured 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()方法在目前的最新版本中已经被废弃,现在只要使用**math/rand** 中rand.Intn()或者其它的随机数方法,其默认会为你设置随机数种子 -
这里使用的是
bufio加os.Stdin来读取命令行输入,bufio提供一个reader接口,但是使用了缓存机制,在一次性读取大量数据时会有更好的性能,这里是为了第3个小实践做铺垫。 -
由于
reader读取的时候会读取所有的输入,所以自然包含了行末的换行符,这里通过**strings.Trim()** 方法来去除换行符,然后通过strconv.Atoi()将读取的字符串转换成整形最后进行比较
-
词典翻译
代码太多了,就不放出来,自行前往仓库查看
-
这个小项目主要讲述如何通过浏览器的debug功能来捕获一些翻译网站的http请求,然后通过模拟这些请求来实现我们想要的功能
-
其中可以使用一些代码生成工具来快速生成代码,而不需要我们自己根据请求来一个一个手打。
-
curl2go: 将从浏览器复制的curl命令转为go语言代码,自行在浏览器搜索一个可用的网站即可。这里提供一个:curl-to-Go: Convert curl commands to Go code -
json2struct: 将从浏览器中获取的响应json转换为结构体,以方便获取之后进行json解析,自行在浏览器搜索一个可用的网站即可。这里提供一个:在线JSON转Golang Struct - JSON中文网、
-
socks5代理
代码太多了,就不放出来,自行前往仓库查看
-
这里需要我们去了解一下socks5协议的原理和细节 SOCKS5 协议原理详解与应用场景分析 - chris599 - 博客园
-
在有了基本的了解之后,其本质就是将两个tcp管道通过一个中间人连接在一起,而socks5服务端就是这个中间人,核心代码:
dest, err := net.Dial("tcp", fmt.Sprintf("%v:%v", addr, port)) if err != nil { return fmt.Errorf("dial dst failed:%w", err) } defer dest.Close() log.Println("dial", addr, port) _, err = conn.Write([]byte{0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0}) if err != nil { return fmt.Errorf("write failed: %w", err) } ctx, cancel := context.WithCancel(context.Background()) defer cancel() go func() { _, _ = io.Copy(dest, reader) cancel() }() go func() { _, _ = io.Copy(conn, dest) cancel() }() <-ctx.Done() return nil其中也可以将
context.WithCancel()替换为sync.WaitGroup来实现两个 goroutine 的同步