这是我参与「第三届青训营-后端场」笔记创作活动的的第1篇笔记。
基础语法
-
组织结构
package main import "fmt" func main() { //... } -
变量
- Go强类型语言,每个变量都有自己的变量类型。
- 常见类型包括整数、浮点数、布尔、字符串等。
- 字符串是内置类型,支持
+和=运算符直接进行操作。 - 声明变量的方式:
var a = "hello" f := float32(e)
-
if-else. 没有小括号,左大括号与 if 同一行。
if a < 0 { // ... } -
循环。Go只有一种循环结构。
for i := 0; i < 10; i++ { } -
switch. 支持多种类型的变量;不会自动顺序执行多个case
switch a { case 1: // ... case 2: // ... } -
数组。长度固定,不常用
var a[5]int -
切片。长度不固定,切片可以看作数组的引用,为数组提供了一种动态的视图。
s := make([]string, 3) -
map 是键-值对的集合。
m := make([string]int) delete(m, "one") -
range
for i, v := range lst {} -
函数。返回值声明在括号后面,支持多个返回值。当函数有多个连续的命名形参类型相同时,可以省略最后一个之前的类型声明。
func count(data []int) (int, error) {} -
指针。相比于C的指针操作非常有限。
-
结构体是字段的集合,其中的字段通过点运算符访问。
type user struct { name string password string } -
结构体方法。Go没有类,但是可以为类型定义方法。方法是拥有接收者参数的函数,类似于其他语言的成员函数。
func (u user) Login() error {} -
错误处理。函数返回值增加一个
err类型的值。 -
字符串操作。
strings.Contains strings.Count strings.HasPrefix strings.Join ... -
字符串格式化
Println() Printf("%v", a) // %v 不需要区分类型,%+v 详细,%#v 更详细 -
JSON处理
json.Marshal() json.Unmarshal() -
时间处理
time.Now() time.Date() t.Sub() time.Parse() -
数字解析
strconv.ParseFloat("1.314", 64) strconv.ParseInt("111", 10, 64) strconv.Atoi("123")//十进制 -
进程信息
os.Args os.Getenv os.Setenv exec.Command
实战
猜谜游戏
程序生成一个随机数,由用户猜出这个数字。实现要点:
- 设置随机种子。
rand.Seed(time.Now().UnixNano()) - 读取用户的输入。可以使用
bufio.NewReader或者Scanfreader := bufio.NewReader(os.Stdin) - 判断逻辑。
- 循环。
在线词典
命令行调用查询单词,得到音标和翻译。实现要点:
- 调用的 API 以及生成代码的方法。
- 可以使用的翻译API有彩云翻译、火山翻译。
- 通过F12找到对应的POST请求,复制为curl。
- 使用 Convert curl commands to code 转换为Go代码。
- 生成 request body。使用结构体表示请求体,并得到序列化的JSON。
- 解析 reponse body。需要将返回的 JSON 结果反序列化为结构体。可以使用工具 JSON转Golang Struct
- 打印结果
- 处理错误情况
SOCKS5 代理
SOCKS是会话层的协议,主要用于客户端与外网服务器之间通讯的中间传递。
- 处理TCP连接
- 处理认证。
- 客户端使用TCP协议连接上Socks5服务器之后,发送一个数据包。服务端可以逐个字节读取处理。
+-----+----------+----------+ | VER | NMETHODS | METHODS | +-----+----------+----------+ | 1 | 1 | 1 to 255 | +-----+----------+----------+ - 服务器需要回应一个数据包。
+-----+--------+ | VER | METHOD | +-----+--------+ | 1 | 1 | +-----+--------+
- 客户端使用TCP协议连接上Socks5服务器之后,发送一个数据包。服务端可以逐个字节读取处理。
- 处理请求。
- 客户端在认证成功之后,需要发送一个数据包来请求服务端。
+-----+-----+-------+------+----------+----------+ | VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT | +-----+-----+-------+------+----------+----------+ | 1 | 1 | X'00' | 1 | Variable | 2 | +-----+-----+-------+------+----------+----------+ - 服务端在对请求进行评估判断之后,回应数据包:
+-----+-----+-------+------+----------+----------+ | VER | REP | RSV | ATYP | BND.ADDR | BND.PORT | +-----+-----+-------+------+----------+----------+ | 1 | 1 | X'00' | 1 | Variable | 2 | +-----+-----+-------+------+----------+----------+
- 客户端在认证成功之后,需要发送一个数据包来请求服务端。
- 建立连接,双向转发数据。
- 根据上一步解析得到的目标地址,建立TCP连接。
- 使用
io.Copy()在两个goroutine中分别进行数据转发。