这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天,学习了一些GO的基础语法,并做了三个小的项目,有所收获
基础语法
关于变量和循环这一类的通用技术很简单,和其他语言大同小异,这里就不赘述了,主要想说一下GO里比较新颖的一些语法和函数
字符串
与C++不同的是,对于string对象,C++是对字符串里的字符进行的操作,而go是利用Strings包里的函数进行的操作
C++中的字符操作方法
C++的string对象上的操作
go的string对象上的操作
json操作
这里主要讲的是如何将一个结构体去序列化转化为json的格式,和怎么从json的格式转换为结构体的方法
- 结构体转化为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"]} - 要求:结构体每一个字段的第一个字母是大写,也就是公开字段
- 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操作
获取unix时间戳:time.now().unix()
数字解析
将字符串转化为int
strconv.Atoi(string)
进程信息
- os.Args 获取命令行参数 ,从文件名开始是第一个
实战
猜数字游戏
- 生成随机数字的方法
maxNum := 100
rand.Seed(time.Now().UnixNano()) //用unix纳秒时间戳生成随机种子
secretNumber := rand.Intn(maxNum)
- 利用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为例,步骤如下:
抓包,根据包构造爬虫语句
- 词典网站:fanyi.caiyunapp.com/#/
- curl改为go语言的网站:curlconverter.com/go/
- json转为struct的网站oktools.net/json2go 将包改为json格式的步骤
- 输入单词,点击翻译按钮,F12,在network中查找dic(这里的翻译包),其payload为json格式的输入载荷,preview为输出的字典形式的json输出,确定此dic包为需要的包
- 然后右键copy cURL,放入上述网站中,转化为go语句,即构成输入。
利用抓到的包制作输入包,即将输入定义为结构体的成员,替换包的输入
- 找到没替换前的含有输入的语句部分,发现明显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)
- 利用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)
输出包的解析,输出包换为结构体的形式,抽取需要的内容
- 利用json.Unmarshal,将json格式的输出转化为一个结构体对象,以提取需要的内容
- 定义结构体对象,找到之前的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)
命令行参数输入,输出希望得到的结果
- 对于输入,在main中修改为命令行参数的内容
func main() {
word := os.Args[1]
query(word)
}
- 对于输出,利用结构体对象输出其中的字段