GO基础语法与项目实战 | 青训营笔记

58 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天,学习了一些GO的基础语法,并做了三个小的项目,有所收获

基础语法

关于变量和循环这一类的通用技术很简单,和其他语言大同小异,这里就不赘述了,主要想说一下GO里比较新颖的一些语法和函数

字符串

与C++不同的是,对于string对象,C++是对字符串里的字符进行的操作,而go是利用Strings包里的函数进行的操作

C++中的字符操作方法

image.png

C++的string对象上的操作

image.png

go的string对象上的操作

image.png

json操作

这里主要讲的是如何将一个结构体去序列化转化为json的格式,和怎么从json的格式转换为结构体的方法

  1. 结构体转化为json
  • 函数: json.Marshal(struct) 或者json.MarshalIndent(struct, "", "\t")//每行用一个tab开头来格式化json串
  • 输入:a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}
  • 输出:fmt.Println(buf)
    // [123 34 78 97...]
    fmt.Println(string(buf)) // {"Name":"wang","age":18,"Hobby["Golang","TypeScript"]}
  • 要求:结构体每一个字段的第一个字母是大写,也就是公开字段
  1. json转化为结构体
  • 函数json.Unmarshal(buf, &struct)
  • 输入:buf:[123 34 78 97...]
  • 输出:main.userInfo{Name:"wang", Age:18, Hobby:[]string{"Golang", "TypeScript"}} [root@VM-16-8-centos 17-json]#
type userInfo struct {
	Name  string
	Age   int `json:"age"`
	Hobby []string
}

func main() {
	a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}
	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"]}

	buf, err = json.MarshalIndent(a, "", "\t")
	if err != nil {
		panic(err)
	}
	fmt.Println(string(buf))

	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"}}
}

time操作

image.png 获取unix时间戳:time.now().unix()

数字解析

将字符串转化为int
strconv.Atoi(string)

进程信息

  • os.Args 获取命令行参数 ,从文件名开始是第一个

image.png

实战

猜数字游戏

  1. 生成随机数字的方法
maxNum := 100 
rand.Seed(time.Now().UnixNano()) //用unix纳秒时间戳生成随机种子
secretNumber := rand.Intn(maxNum) 
  1. 利用bufio的方式读取输入
reader := bufio.NewReader(os.Stdin) //打开stdin的标准输入文件为流
input, err := reader.ReadString('\n') //从reader流读取输入,以换行为结束
input = strings.Trim(input, "\r\n") //从输入中裁剪去换行
guess, err := strconv.Atoi(input) //字符串转换为Int

在线词典

这个项目设计抓包,包转化为json格式,json格式转化为结构体,命令行参数的使用。
以调用网页的词典API为例,步骤如下:

抓包,根据包构造爬虫语句
  1. 输入单词,点击翻译按钮,F12,在network中查找dic(这里的翻译包),其payload为json格式的输入载荷,preview为输出的字典形式的json输出,确定此dic包为需要的包
  2. 然后右键copy cURL,放入上述网站中,转化为go语句,即构成输入。
利用抓到的包制作输入包,即将输入定义为结构体的成员,替换包的输入
  1. 找到没替换前的含有输入的语句部分,发现明显type和source的内容应该自定义,因此构造此结构体,替换输入
client := &http.Client{}
var data = strings.NewReader(`{"trans_type":"en2zh","source":"good"}`)
req, err := http.NewRequest("POST","https://api.interpreter.caiyunai.com/v1/dict", data)
  1. 利用json.Marshal转化结构体为输入,生成流的语句也应该相应替换为bytes.NewReader,因为转化后的json为byte数组
type DictRequest struct {
	TransType string `json:"trans_type"`
	Source    string `json:"source"`
	UserID    string `json:"user_id"`
}

client := &http.Client{}
	request := DictRequest{TransType: "en2zh", Source: "good"}
	buf, err := json.Marshal(request)
	var data = bytes.NewReader(buf)
	req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data)
        
输出包的解析,输出包换为结构体的形式,抽取需要的内容
  1. 利用json.Unmarshal,将json格式的输出转化为一个结构体对象,以提取需要的内容
  2. 定义结构体对象,找到之前的dic包,复制其输出包,将其放入之前提到的第三个网站,转为结构体格式,定义结构体对象后,放入步骤1中,得到结构体对象。
resp, err := client.Do(req)
	defer resp.Body.Close()
	bodyText, err := ioutil.ReadAll(resp.Body)
	var dictResponse DictResponse
	err = json.Unmarshal(bodyText, &dictResponse)
	fmt.Printf("%#v\n", dictResponse)
命令行参数输入,输出希望得到的结果
  1. 对于输入,在main中修改为命令行参数的内容
func main() {
	word := os.Args[1]
	query(word)
}

  1. 对于输出,利用结构体对象输出其中的字段

对于Socket5的实验,自己理解的一般,一些协议和函数并没有深入认识,日后加深理解后会再补充