Go 语言原理与实践| 青训营笔记
这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
go语言基础
go语言的特点
- 高并发,高性能
- 丰富的标准库
- 垃圾回收机制
- 跨平台(交叉编译)
与其他语言的不同
- 变量定义不同
var name string = "zhangsan" //指明变量类型的定义
var name = "zhangsan" //自动分辨类型的定义
name := "张三" //省略var的变量定义
- 常量定义
const PI float = 3.1415 //常量的定义
- if-else用法
//特有:if中没有括弧,且判读语句和else后必须加{
if a > 1 {
fmt.Println(a)
}else{
fmt.Println(1)
}
- for循环
//go中只含有for一种循环
for i := 0; i < count; i++ {
fmt.Println(i)
}
- 数组
var a [5]int //定义数组,内容为空
b := [5]int{1,2,3,4,5} //定义数组,并赋值
6.切片
s := make([]stirng,3) //创建一个空值切片,但是占空间
s = append(s,"hello") //在切片后面添加元素,如果使用make,像上面,则插在索引为3的位置
s := []string{"nihao", "world"} //创建有初值的切片
- map
maps := make(map[string]int) //创建一个空map,没有数据
maps["no1"] = 1 //赋值
delete(maps,"no1") //删除键值对
mapA := map[string]int{"zhangsan":12,"lisi":14} //建立含有初值的map
- json
json.Marshal() //结构体序列化为字节数组
json.Unmarshal() //将字节数组反序列化为结构体
项目总结
1.猜谜游戏
分为一下三个步骤
- 获取一个随机数
maxNum := 100 //随机数的最大值为100
rand.Seed(time.Now().UnixNano()) //使用rand之前,需要使用系统时间戳,使其产生不同的数字
secretNum := rand.Intn(maxNum) //产生随机数字
fmt.Printf("The secret number is %v\n", secretNum)
- 用户输入一个数字
//读一行数据
input, err := reader.ReadString('\n')
if err != nil {
fmt.Println("An error occured while reading input.Please try again", err)
return
}
input = strings.TrimSuffix(input, "\r\n") //去掉换行符和回车
//转换成数字
guess, err1 := strconv.Atoi(input)
if err1 != nil {
fmt.Println("Invalid input. Please enter on integer value", err1)
return
}
- 和随机数进行比较
if guess > secretNum {
fmt.Println("Your guess is bigger than secret number.Please try again")
} else if guess < secretNum {
fmt.Println("Your guess is smaller than secret number.Please try again")
} else {
fmt.Println("Correct,you Legend!")
break
}
这个练习题较为简单,主要是积累一函数功能,像随机数生成,获取用户命令行输入
2.简易爬虫,获取单词翻译
主要步骤如下
- 获取要查询的单词
- 发起Post请求
- 接收Response
- 处理响应结果
学到一种go的思想,使用 结构体 来接收和但序列化json格式数据,使用到两种快速生成代码工具,
- 使用url快速生成http响应抓包的方法 curlconverter.com/go/
- 将json语句转化成go语言的结构体 oktools.net/json2go
- 快速生成的http请求代码
func main() {
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)
if err != nil {
log.Fatal(err)
}
//...
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", bodyText)
}
对代码进行分析,可以查询固定的单词,查找其他单词需要更改代码,所以需要设计一个变量来传递查找单词,最后的输出结果,太过杂乱,需要对响应结果进行分析,拆分出有效的结果并输出
- 设置单词变量
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, `usage:simpleDict WORD
example:simpleDict hello
`)
os.Exit(1)
}
word := os.Args[1] //从命令行取到查找单词
- 处理请求内容,发出Post请求
type DictResquest struct {
TransType string `json:"trans_type"`
Source string `json:"source"`
UserID string `json:"user_id"`
}
进行json转换的结构体,变量要已大写字母命名,json:"trans_type"可以改变返回值的命名
request := DictResquest{TransType: "en2zh", Source: word} //初始化结构体
buf, err := json.Marshal(request) //返回一个字节数组
if err != nil {
log.Fatal(err)
}
data := bytes.NewReader(buf) //将字节数组转换成流
req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data) //发起一个POST的http请求
if err != nil {
log.Fatal(err)
}
- 发出请求
resp, err := client.Do(req) //执行请求,返回响应对象
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close() //关闭响应
- 处理响应结果
var dictResponse DictResponse
err = json.Unmarshal(bodyText, &dictResponse)/将json反序列化为结构体
if err != nil {
log.Fatal(err)
}
fmt.Println(word, "UK:", dictResponse.Dictionary.Prons.En, "US:", dictResponse.Dictionary.Prons.EnUs)
for _, v := range dictResponse.Dictionary.Explanations {
fmt.Println(v)
}
对响应的结构体由快速生成代码程序实现,最后就是从结构体中拿取数据
3.SOCKS5代理
之后补充
总结
go语言使用起来确实比较简单,之前使用java,在导入库方面,感觉到了go的好处,几乎都是使用内部标准库就能轻松的实现网络编程.会更加投入到go的学习中,体会go语言的强大,以及为什么能被大厂青睐.