[ day2 走进Go语言续 | 青训营笔记]

41 阅读2分钟

上次语法说到了结构体,今天我们继续。

错误处理

在 Go 语言中我们习惯用一个单独的返回值来传递错误信息,这样可以准确的定位到错误的位置,也很方便进行流程控制。

例如在以下函数中,使用了 err 类型来处理出错的情况。

func findUser(users []user, name string) (v *user, err error) {
	for _, u := range users {
		if u.name == name {
			return &u, nil
		}
	}
	return nil, errors.New("not found")
}

JSON 处理

对于一个现有的结构体我们只需要将结构体的每一个成员首字母大写(即让其变为公开字段)即可使用 json.Marshal 方法对其进行序列化。同时我们也可以对一个序列化后的字符串使用 json.Unmarshal 进行反序列化。在输出时要使用 string 类型转换,否则将输出为十六进制数字。如果不想要输出的字段名为大写,可以给字段后加加一个 tag 或者说是别名。如下所示:

type userInfo struct {
	Name  string
	Age   int `json:"age"`
	Hobby []string
}

获取进程信息

我们可以使用 os 包来获取进程和系统的一些信息,例如使用 os.Args 就可以获取到运行程序时的参数。os.Getenv(key string)os.Setenv(key string, balue string) 可以获取和设置环境变量。exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput() 可以快速启动子进程,并获取输出。

课后作业

使用 scanner 替换 reader

// ...
scanner := bufio.NewScanner(os.Stdin)
for {
	scanner.Scan()
	input := scanner.Text()
	guess, err := strconv.Atoi(input)
	if err != nil {
		fmt.Println("Invalid input. Please enter an integer value")
		continue
	}
	fmt.Println("You guess is", guess)
	// ...
}

命令行在线词典

这个程序需要做到在调用程序时,将要查询的英文单词作为程序参数传入,程序将调用第三方 API 查询出单词的音标与含义输出到控制台,通过这个程序可以学习到如何使用 Go 语言来发送 Http 请求以及如何解析 JSON。

  1. 从浏览器获取请求命令
  2. 生成 Go 语言程序
  3. 创建请求
  4. 发起请求
  5. 处理响应
  6. 完善请求
  7. 解析响应

完善代码:

//...
type DictRequest struct {
	//...
}

type DictResponse struct {
	// ...
}

func query(word string) {
	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...
	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)
	}
}

func main() {
	if len(os.Args) != 2 {
		fmt.Fprintf(os.Stderr, `usage: simpleDict WORD example: simpleDict hello
		`)
		os.Exit(1)
	}
	word := os.Args[1]
	query(word)
}

最后

今天的课程带我快速上手了 Go 语言,我学会了基本语法与基本的HTTP请求发送方式,关于最后一个 SOCKS5 代理服务器我还需要反复学习,以更加深入理解。今天的笔记就到此为止,明天继续更新~~