go语言入门| 青训营笔记

55 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第一篇笔记

image.png

本届青训营后端专场的第一节课是对go语言基础语法的一些基本介绍,主要内容如下:

1.课程ppt链接: bytedance.feishu.cn/file/boxcnQ…

2.课程主要内容分为以下3个部分:

image.png

简介部分主要介绍了go语言的一些基本特性与特点,紧接着是基础语法以及标准库的介绍,最后老师通过几个实例来帮助我们更快的上手go语言。

首先是go语言的基础语法部分,其中个人认为比较重要的部分是切片和结构体部分,还有go语言中比较重要的interface。 切片的示例如下

s := make([]string, 3)
s[0] = "a"
s[1] = "b"
s[2] = "c"
fmt.Println("get:", s[2])   // c
fmt.Println("len:", len(s)) // 3

s = append(s, "d")
s = append(s, "e", "f")
fmt.Println(s) // [a b c d e f]

c := make([]string, len(s))
copy(c, s)
fmt.Println(c) // [a b c d e f]

fmt.Println(s[2:5]) // [c d e]
fmt.Println(s[:5])  // [a b c d e]
fmt.Println(s[2:])  // [c d e f]

good := []string{"g", "o", "o", "d"}
fmt.Println(good) // [g o o d]
复制代码

其中除了基本的用法,还应该注意的是,切片的实质,是框出一块可以扩容的内存,切片实际上是引用类型。在切片的扩容过程中,当切片底层所对应的数组容量不够时,会用一个容量为原数组两倍的新数组进行替换。由于是引用类型,对于赋值的操作,两个切片其实共享的是同一个底层数组,故对于其中一个的修改会影响另一个。

结构体的示例如下:

package main

import "fmt"

type user struct {
	name     string
	password string
}

func (u user) checkPassword(password string) bool {
	return u.password == password
}

func (u *user) resetPassword(password string) {
	u.password = password
}

func main() {
	a := user{name: "wang", password: "1024"}
	a.resetPassword("2048")
	fmt.Println(a.checkPassword("2048")) // true
}


复制代码

与c++不同,go语言中结构体可以拥有自己的成员函数,类似于c++中的class,这是go语言面向对象编程的基础。struct与interface紧密联系,实现interface中所有方法的结构体即可通过接口实例来接受,特别的是,go语言中的所有类型都实现了空接口。通过接口,可以实现面向对象中的多态特性。

本节课的最后,通过了几个小项目来巩固我们对于go的基本语法的掌握。在此重点记录词典小项目: 该项目通过浏览器开发者工具找到彩云词典中的http请求中翻译词语的部分(dict服务),通过curl转换工具转换为go语言的服务请求代码。具体代码如下:

	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)
	}
}
复制代码

以此实现通过go程序发送请求实现单词翻译的功能。其中用到的标准库有:创建https请求的net/http,支持网络io的ioutils,序列化和反序列化的json等。