这是我参与「第五届青训营 」笔记创作活动的第1天。由于整理笔记花费比较多的时间,今天整理完一篇。
error 错误处理
import "errors"
由于函数的返回值天然可以有多个,所以在业务处理的过程中,通常都会在返回值中添加一个错误值。
- 当一切正常时,返回正确的返回值和nil(null),表示没有错误信息
- 若发生错误时,则错误信息的返回值不为空,其业务返回值为空
error库可以用来创建一个错误信息error.New("...")
func findUser(users []user, name string) (v *user, err error) {
for _, u := range users {
if u.name == name {
// error为空,未发生错误
return &u, nil
}
}
// 返回nil值,与错误信息
return nil, errors.New("not found")
}
在调用某一个业务函数后,需要对其返回值进行判断,如果第二个参数 err 为空,则直接处理业务返回值;如果不为空,则需要打印错误日志。
u, err := findUser([]user{{"wang", "1024"}}, "wang")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(u.name) // wang
string库
import "string"
- string初始化:
a := "hello",使用len(a)查看字符串的长度(对于中文字符来说,一个中文字符所对应的字符长度>1)
b := "你好"
fmt.Println(len(b)) // 6
// 当字符串中需要有 "" 则需要使用 `` 来包装
s = `{"key": "value"}`
- 判断是否包含另外一个字符串:
strings.Contains(a, "ll") // true
- 对字符串内字符串计数
strings.Count(a, "ll") // 2
- 是否有前缀
strings.HasPrefix(a, "he") //true
- 是否有后缀
strings.HasSuffix(a, "llo") // true
- 寻找指定字符串的开始位置,若不存在,则返回-1
strings.Index(a, "x")
- 字符串拼接,第二个参数表示字符串之间的分隔符
strings.Join([]string{"he", "llo"}, "-")
- 重复字符串
strings.Repeat(a, 2)
- 替换字符串中的子字符串,第四个参数为替换的个数限制,如果该参数小于0,则对替换的个数没有限制
strings.Replace(a, "l", "L", 1) // heLlo
- 根据对应分隔符将字符串转换为字符串数组
strings.Split("a-b-c", "-") // [a b c]
- 转大/小写
strings.ToLower(a) // 小写 hello
strings.ToUpper(a) // 小写 HELLO
fmt 输入输出库
import "fmt"
输出
%v对任何变量值进行输出%+v针对结构体,其输出结构体内字段的名称%#v针对结构体,其输出结构体的名称及其内部字段的名称
type point struct {
x, y int
}
p := point{1, 2}
fmt.Printf("p=%v\n", p) // p={1 2}
fmt.Printf("p=%+v\n", p) // p={x:1 y:2}
fmt.Printf("p=%#v\n", p) // p=main.point{x:1, y:2}
输出浮点数时,使用 %.nf 来格式化为保留n为小数的浮点数
输入
go中的 Scanf 函数与C中的scanf用法是相似的,第一个参数为需要传入的格式,第二个参数为需要输入的变量的地址。
由于最后键入的是回车,所以在第一个参数中添加 \n 符,以读入回车符。
fmt.Scanf("%s\n", &s)
json库
import "encoding/json"
json 常用于记录结构体数据,在结构体字段中,必须保证字段的开头为大写,才能被序列化。如果需要在输出时使用别于字段本身的名字,则需要添加 tag 。
type userInfo struct {
Name string
Age int `json:"age"` //添加json的tag别名,则输出的时候会使用该别名
Hobby []string
}
- 结构体的序列化:将结构体转化为字节数组(其中都是字符所对应的ASCII码或Unicode),该字节数组需要转化为 string 才能正常输出。在输出时,添加了 tag 的字段将输出别名(age)
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...] 字节数组
// {"Name":"wang","age":18,"Hobby":["Golang","TypeScript"]}
fmt.Println(string(buf))
buf, err = json.MarshalIndent(a, "", "\t")
if err != nil {
panic(err)
}
fmt.Println(string(buf))
- 序列化字符串的格式化:使用
MarshalIndent函数将字符串进行format操作。其内部会根据变量的层次关系将结构体换行,并添加缩进,函数的参数列表如下,其中 indent 表示每次缩进使用的字符串,prefix 每一行前加上的字符 MarshalIndent(v any, prefix string, indent string)
buf, err = json.MarshalIndent(a, "x", "\t")
if err != nil {
panic(err)
}
fmt.Println(string(buf))
// {
// "Name": "wang",
// "age": 18,
// "Hobby": [
// "Golang",
// "TypeScript"
// ]
// }
- 结构体的反序列化:使用字节数组将其值赋值到结构体中。需要注意的是,由于需要对结构体进行修改,所以需要传入结构体的地址(加上地址符)
var b userInfo
// 反序列化到一个空的变量中
err = json.Unmarshal(buf, &b)
if err != nil {
panic(err)
}
// main.userInfo{Name:"wang", Age:18, Hobby:[]string{"Golang", "TypeScript"}}
fmt.Printf("%#v\n", b)
time 时间库
import "time"
- 获取当前时间,可以通过
Unix()获取时间戳
now := time.Now()
now.Unix() // 获取时间戳
- 构建一个带市区的时间
// Date(year int, month time.Month, day int, hour int, min int, sec int, nsec int, loc *time.Location)
t := time.Date(2022, 3, 27, 1, 25, 36, 0, time.UTC)
- 根据时间的一些方法获取其属性
// 2022 March 27 1 25
fmt.Println(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute())
- 时间的格式化:使用传入 Format 函数中的参数的时间的格式对给定的时间格式化,即传入的时间为一种样例
// 2022/03/27 01:25:36
fmt.Println(time.Now().Format("2006/01/02 15:04"))
- 时间差
t2 := time.Date(2022, 3, 27, 2, 30, 36, 0, time.UTC)
diff := t2.Sub(t)
fmt.Println(diff) // 1h5m0s
fmt.Println(diff.Minutes(), diff.Seconds()) // 65 3900
- 由字符串转为
time类型变量:第一个参数为解析的字符串所依据的时间格式,第二个参数为需要解析的时间字符串
t3, err := time.Parse("2006-01-02 15:04:05", "2022-03-27 01:25:36")
strconv 字符串转换
import "strconv"
- 解析 float 浮点数
f, err := strconv.ParseFloat("1.234", 64)
- 解析 int 整数:第二个参数表示解析使用的进制数,第三个参数表示存储的位数(精度)。如果说进制的参数为0,则系统自动检测。
n, err := strconv.ParseInt("111", 10, 64)
n, _ = strconv.ParseInt("0x1000", 0, 64)
- 字符串和int互相转换
n2, err := strconv.Atoi("123") // 字符串转int
// 如果传入的是非数字的字符串,则会产生错误。
n3 := strconv.Itoa(123) // int转字符串
获取进程信息
import ( "os" "os/exec" )
- 获取命令行中的参数,第一个参数为执行的程序的名称,用户在命令行中输入的其他参数从第二个开始(得到的是一个字符串数字)
os.Args
- 环境变量的读取和修改
os.Getenv("PATH")
os.Setenv("AA", "BB")
- 执行命令行命令,
CombinedOutput用于执行命令且返回对应的错误信息
buf, err := exec.Command("CommandName","param1","param2",...).CombinedOutput()