Go 语言原理与实践| 青训营笔记

98 阅读3分钟

Go 语言原理与实践| 青训营笔记

这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天

go语言基础

go语言的特点

  • 高并发,高性能
  • 丰富的标准库
  • 垃圾回收机制
  • 跨平台(交叉编译)

与其他语言的不同

  1. 变量定义不同
  var name string = "zhangsan" //指明变量类型的定义
  var name = "zhangsan"        //自动分辨类型的定义
  name := "张三"                //省略var的变量定义
  1. 常量定义
  const PI float = 3.1415  //常量的定义
  1. if-else用法
//特有:if中没有括弧,且判读语句和else后必须加{
  if a > 1 {
    fmt.Println(a)
  }else{
    fmt.Println(1)
  }
  1. for循环
//go中只含有for一种循环
	for i := 0; i < count; i++ {
		fmt.Println(i)
	}
  1. 数组
    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"}  //创建有初值的切片
  1. map
    maps := make(map[string]int)   //创建一个空map,没有数据
    maps["no1"] = 1         //赋值
    delete(maps,"no1")      //删除键值对
    mapA := map[string]int{"zhangsan":12,"lisi":14}   //建立含有初值的map
  1. 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格式数据,使用到两种快速生成代码工具,

  1. 使用url快速生成http响应抓包的方法 curlconverter.com/go/
  2. 将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)
}

对代码进行分析,可以查询固定的单词,查找其他单词需要更改代码,所以需要设计一个变量来传递查找单词,最后的输出结果,太过杂乱,需要对响应结果进行分析,拆分出有效的结果并输出

  1. 设置单词变量
if len(os.Args) != 2 {
		fmt.Fprintf(os.Stderr, `usage:simpleDict WORD
		example:simpleDict hello
		`)
		os.Exit(1)
	}
	word := os.Args[1]  //从命令行取到查找单词
  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)
	}
  1. 发出请求
resp, err := client.Do(req) //执行请求,返回响应对象
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close() //关闭响应
  1. 处理响应结果
	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语言的强大,以及为什么能被大厂青睐.