注:本文搬运了一些我青训营期间听课的笔记(我一般直接用注释或者记笔记本上),不保证正确性,而且有些地方可能比较乱,大家看个乐就行了。
基础语法部分
function
go语言中的函数在定义时函数类型是后置的,但括号的位置仍然紧贴着函数名:func 函数名(参数名1 参数类型1, 参数名2 参数类型2, ...) 函数类型。
与c语言或c++不同的是,go语言中的函数可以返回多个值,这是go语言很有特色且非常便利的一个点,具体的写法就是把上面的函数类型替换成一个包含所有需要返回的值的元组:( 返回值名称1 返回值类型1, 返回值名称2 返回值类型2, ...)。可以看到,要返回多个值的时候需要给每个需要返回的参数加个名字,并且这些参数在函数中可以被赋值,最后return对应的参数名即可。以13行为例,此处第一个返回值是真正的函数结果,第二个返回值是错误信息,增加一个错误信息的返回为后续的问题排查提供了便利。
package main
import "fmt"
func add(a int, b int) int {
return a + b
}
func add2(a, b int) int {
return a + b
}
func exists(m map[string]string, k string) (v string, ok bool) {
v, ok = m[k]
return v, ok
}
func main() {
res := add(1, 2)
fmt.Println(res) // 3
v, ok := exists(map[string]string{"a": "A"}, "a")
fmt.Println(v, ok) // A True
}
json
json的全称是JavaScript Object Notation,是一种轻量级的数据交换格式,主要用在客户端与服务器端的数据交换,与具体编程语言无关。
在go语言中,结构体可以与json字符串互相转化。具体而言,只要一个结构体里每个字段的首字母是大写的(公开字段),这个结构体可以用json.Marshal()序列化,变成json字符串(如第8行的结构体);另外还可以通过加json tag(如第10行)使这个字段以json字符串输出时可以自定义字段名称;第23行的json.MarshalIndent()与前面的函数功能类似,但是增加了prefix和indent(缩进)。如果要将json字符串转化为结构体,只需要用json.Unmarshal()反序列化即可(如第30行)。
顺便提一下第34行中打印格式的知识点。go语言中Printf()用法类似C,但是可以用%v打印任意类型的变量,不需要手动区分变量的类型(系统会自动识别),这样在许多场合下方便了很多,如果要得到更详细的结果,可以使用%+v和%#v。
package main
import (
"encoding/json"
"fmt"
)
type userInfo struct {
Name string
Age int `json:"age"` // 输出效果见21行
Hobby []string
}
func main() {
a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}
buf, err := json.Marshal(a)
if err != nil {
panic(err) // 逐级终止调用该函数的函数
}
fmt.Println(buf) // [123 34 78 97...] // 不加string会打印出十六进制的编码
fmt.Println(string(buf)) // {"Name":"wang","age":18,"Hobby":["Golang","TypeScript"]}
buf, err = json.MarshalIndent(a, "", "\t")
if err != nil {
panic(err)
}
fmt.Println(string(buf))
var b userInfo
err = json.Unmarshal(buf, &b) // 反数列化到一个空的变量里面
if err != nil {
panic(err)
}
fmt.Printf("%#v\n", b) // main.userInfo{Name:"wang", Age:18, Hobby:[]string{"Golang", "TypeScript"}}
}