Go基础与项目笔记
由于笔者有一定的其他语言基础,因此本文主要总结一些Go语言与原来使用的语言(Java/C++)不一样的特性。
1. Go语言基础
切片和子切片
子切片和切片共用底层数据,若修改子切片数据,切片数据也会改变。
package main
import "fmt"
func main() {
s := make([]int, 0)
for i := 0; i < 10; i++ {
s = append(s, i)
}
subS := s[:4] // 子切片:[0 1 2 3]
subS[1] = 10
fmt.Println(s) // [0 10 2 3 4 5 6 7 8 9],原切片s被修改
// 如果要复制新的子切片,需要额外创建切片,并使用拷贝
subS2 := make([]int, len(s[4:]))
copy(subS2, s[4:]) // [4 5 6 7 8 9]
subS2[3] = 10
fmt.Println(subS2) // [4 5 6 10 8 9]
fmt.Println(s) // [0 10 2 3 4 5 6 7 8 9],修改子切片后,原切片没被修改
}
字符串格式化
Go语言提供了一个区别于C++/Java的简易字符串格式化方法:
fmt.Printf("s=%v\n", s) // s=hellos)
fmt.Printf("n=%v\n", n) // n=123
fmt.Printf("p=%v\n", p) // p={1,2}
fmt.Printf("p=%+v\n", p) // p={x:1 y:2}
fmt.Printf("p=%#v\n", p) // p=main.point{x:1,y:2}
使用%v可以用来格式化所有类型的变量,其中使用+和#字符可以控制结构体打印的细节多少。
Json处理
在Http请求中,需要使用Json格式字符串与前端进行交互。因此,我们需要熟悉Golang中结构体与JSON格式字符串如何进行快速转换。
package main
import (
"encoding/json"
"fmt"
)
type userInfo struct {
Name string
Age int `json:"age"`
Hobby []string
}
func main() {
a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}
// 序列化:输出json格式的字符串(常用)
buf, err := json.Marshal(a)
if err != nil {
panic(err)
}
fmt.Println(buf) // [123 34 78 97...]
fmt.Println(string(buf)) // {"Name":"wang","age":18,"Hobby":["Golang","TypeScript"]}
// 序列化:输出有换行符的json格式字符串(可视化用?)
buf, err = json.MarshalIndent(a, "", "\t")
if err != nil {
panic(err)
}
fmt.Println(string(buf))
// 反序列化:将Json格式字符串反序列化成结构体
var b userInfo
err = json.Unmarshal(buf, &b)
if err != nil {
panic(err)
}
fmt.Printf("%#v\n", b) // main.userInfo{Name:"wang", Age:18, Hobby:[]string{"Golang", "TypeScript"}}
}
2. 在线词典项目
本项目旨在用Go实现一个调用外部词典API的一个程序,使得用户在命令行输入一个单词,程序会调用词典API输出单词释义。
快速构造与外部API交互代码
要调用外部API之前,首先需要构建一个能与API交互的http请求与响应。我们具体需要做的有:
- 构建请求头(header)——通过抓包post请求快速构建请求头代码: Curl Converter
- 构建post请求体(确定url、request body里的参数等)
- 正确接收API响应的信息(需要构建接收响应信息的结构体)——通过抓包响应信息快速构建接收响应的结构体: oktools.net/json2go
3. Socks5代理项目
本项目使用Go搭建了一个简易Socks5协议代理服务器,学到了代理服务器的原理与一些底层协议。协议细节较为复杂,待搞懂。