这是我参与「第五届青训营 」笔记创作活动的第1天。
学习内容:
今天开始go语言的入门学习,首先根据青训营的课程学习了go语言的原理和三个项目的实战,因为第一次接触go,课后又阅读了Go语言圣经(中文版)进行补充。
课程内容:
本节课程主要分为三部分:
- Go 语言简介
- Go 语言开发入门,包括开发环境配置、基础语法、标准库
- Go 实战练习,包括三个实战项目
什么是go:
高并发、高性能;语法简单、学习曲线平缓;丰富的标准库;完整的工具链;静态链接;快速编译;跨平台;垃圾回收。
基础语法:
- 变量声明;有两种方式:
var 变量名 (变量类型) = 变量值以及变量名 := 变量值。声明常量就把var改成const即可。 - if else条件语句;与其他语言类似,if的条件不必加括号,执行语句在花括号内,第一个花括号必须与if同行。
if 条件 {
执行语句
}
- 循环;go没有while,只有for,最简单用for加花括号表示一个死循环。
for 变量声明; 终止条件; 变量改变{
执行语句
}
- swich;与其他语言类似,条件变量不必加括号,不用添加break就可以跳过之后的执行语句;条件变量可以是任何类型,甚至可以省略,可以替换成if条件语句。
switch 条件变量 {
case 值1:执行语句
case 值2:执行语句
case 值3:执行语句
......
}
- 数组;与其他语言类似,在业务代码中不常用,一般用切片;
- 切片;可变长度,用make来定义
切片名 := make(变量类型,初始长度),可以用append追加元素切片s = append(切片s,追加元素1,追加元素2,......),有类似python的切片操作。 - map;用make来定义
map名 := make(map[键类型]值类型),通过方括号写入和读取键值对,使用delete删除某一键值对。在go中,map完全无序的,遍历输出是随机顺序。 - range;对一个数组使用range会返回两个值,一个索引,一个是值。
- 指针;用途有限,主要对一个变量进行改变。
- 结构体;结构体方法;有带指针和不带指针两种;
标准库:
- errors: 主要用来判断error是否存在(nil or not)。
- strings: 字符串操作。
- fmt: 字符串格式化;%v可以打印任何类型。
- json: 一个结构体可以处理成json字符串,也可以反序列化。
- time: 时间处理,常用time.Now()获取当前时间。获取date的格式是一个固定的时间。
- strconv:字符串和数字的转换。
实战项目:
猜数字游戏:
maxNum := 100
rand.Seed(time.Now().UnixNano())
secretNumber := rand.Intn(maxNum)
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
}
}
在线词典:
client := &http.Client{}
request := DictRequest{TransType: "en2zh", Source: word}
buf, err := json.Marshal(request)
if err != nil {
log.Fatal(err)
}
var data = bytes.NewReader(buf)
req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Connection", "keep-alive")
req.Header.Set("DNT", "1")
req.Header.Set("os-version", "")
req.Header.Set("sec-ch-ua-mobile", "?0")
req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36")
req.Header.Set("app-name", "xy")
req.Header.Set("Content-Type", "application/json;charset=UTF-8")
req.Header.Set("Accept", "application/json, text/plain, */*")
req.Header.Set("device-id", "")
req.Header.Set("os-type", "web")
req.Header.Set("X-Authorization", "token:qgemv4jr1y38jyq6vhvi")
req.Header.Set("Origin", "https://fanyi.caiyunapp.com")
req.Header.Set("Sec-Fetch-Site", "cross-site")
req.Header.Set("Sec-Fetch-Mode", "cors")
req.Header.Set("Sec-Fetch-Dest", "empty")
req.Header.Set("Referer", "https://fanyi.caiyunapp.com/")
req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9")
req.Header.Set("Cookie", "_ym_uid=16456948721020430059; _ym_d=1645694872")
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
if resp.StatusCode != 200 {
log.Fatal("bad StatusCode:", resp.StatusCode, "body", string(bodyText))
}
var dictResponse DictResponse
err = json.Unmarshal(bodyText, &dictResponse)
if err != nil {
log.Fatal(err)
}
fmt.Println(word, "UK:", dictResponse.Dictionary.Prons.En, "US:", dictResponse.Dictionary.Prons.EnUs)
for _, item := range dictResponse.Dictionary.Explanations {
fmt.Println(item)
}
Socks5代理:
原理:客户端不直接与服务端连接。
总的来说,前两个实践项目是比较简单的,最后的代理稍难。