2.1 错误处理
2.1.1 nil
在Go语言中,如果你声明了一个变量但是没有对它进行赋值操作,那么这个变量就会有一个类型的默认零值。这是每种类型对应的零值:
bool -> false
numbers -> 0
string -> ""
pointers -> nil
slices -> nil
maps -> nil
channels -> nil
functions -> nil
interfaces -> nil
2.1.2 errors
- errors.New()
返回一个error类型
func division(number1, number2 int) (float64, error) {
if number2 == 0 {
return 0.0, errors.New("division by zero") //返回错误,表示除数为0
}
return float64(number1) / float64(number2), nil
}
panic和recover
panic(“语句”)程序终止运行
当
panic()触发的宕机发生时,panic后面的代码将不会被执行,但是在panic()函数前面的已经执行过的defer语句依然会在宕机发生时执行defer中的延迟函数。
func funcA() {
fmt.Println("func A")
}
func funcB() {
panic("panic in B")
}
func funcC() {
fmt.Println("func C")
}
func funcD() {
fmt.Println("func D")
}
func main() {
defer funcA()
defer funcC()
fmt.Println("this is main")
funcB()
defer funcD()
}
运行结果:
this is main
func C
func A
panic: panic in B
goroutine 1 [running]:
main.funcB(...)
/home/wangxm/go_work/src/chapter05/demo.go:12
main.main()
/home/wangxm/go_work/src/chapter05/demo.go:29 +0xca
exit status 2
recover()防止程序崩溃。
当
recover捕获到panic时,不会造成整个进程的崩溃,它会从触发panic的位置退出当前函数,然后继续执行后续代码
2.1.4 错误处理实例
import (
"errors"
"fmt"
)
type user struct {
name string
password string
}
func findUser(users []user, name string) (v *user, err error) {
for _, u := range users {
if u.name == name {
return &u, nil //返回u变量地址,和nil错误
}
}
return nil, errors.New("not found") //返回零值用户,和错误
}
func main() {
u, err := findUser([]user{{"wang", "1024"}}, "wang")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(u.name) // wang
if u, err := findUser([]user{{"wang", "1024"}}, "li"); //err != nil {
fmt.Println(err) // not found
return
} else {
fmt.Println(u.name)
}
}
这个代码片段中,findUser函数的第一个参数是一个[]user类型的切片,表示用户列表。而在调用findUser函数时,传递给它的第一个参数是一个切片字面量[]user{{"wang", "1024"}}。
为什么使用两个大括号{{"wang", "1024"}}呢?这是因为在Go语言中,大括号{}用于
创建和初始化结构体类型的值。在这个例子中,user是一个结构体类型,它有两个字段name和password。所以{{"wang", "1024"}}表示创建一个user类型的结构体值,其中name字段的值是"wang",password字段的值是"1024"。因为findUser函数的第一个参数是一个用户列表,所以需要传递一个切片,即使只有一个用户。所以使用两个大括号{{"wang", "1024"}}来创建一个
只包含一个用户的切片
2.2 字符串包
需要引进
strings包 (以 a:="hello"为例)
- 将两个字符串用指定符号相连
strings.Join([]string{"he","llo"},"_"),结果为“he_llo” - 索引字符串
strings.Index(a, "ll"),结果为2 - 查询字符串
strings.Contains(a, "ll"),结果为true - 计数字符串
strings.Count(a, "l"),结果为2 - 重复字符串
strings.Repeat(a, 2),结果为“hellohello” - 去除字符
strings.Split("a-b-c", "-"),结果为[a b c] - 大小写
strings.ToLower(a)strings.ToUpper(a) - 长度
len(a)
2.3 格式化
- %v是通用格式化占位符
fmt.Printf("s=%v\n", s) %+v是%v的一个变体,它会在打印结构体时,除了打印字段的值外,还会打印字段的名称和冒号。%#v是一种格式化字符串的占位符,用于打印结构体的详细信息,包括字段名和字段值。
2.4 json包
json.Marshal()将数据序列化为 JSON 字符串json.MarshalIndent(“数据结构”,“缩进字符串”,“缩进字符数”)函数用于将 Go 数据结构转换为 JSON 格式的字符串,并且可以按照指定的缩进格式进行格式化
a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}
buf, err := json.Marshal(a)
fmt.Println(buf) // [123 34 78 97...]
fmt.Println(string(buf)) // {"Name":"wang","age":18,"Hobby":["Golang","TypeScript"]}
json.Unmarshal()函数用于将 JSON 数据解析为 Go 语言中的结构体或者其他数据类型
type Student struct {
// 变量首字母大写才能被解析
Name string `json:"name"` // name表示在json中Name的字段名
Age int `json:"age"` //json标签
}
func main() {
student := Student{
Name: "韩信",
Age: 24,
}
marshal, _ := json.Marshal(&student)
s := string(marshal)
fmt.Println("序列化后:", s) // 序列化后: {"name":"韩信","age":24}
// 使用Unmarshal反序列化
json.Unmarshal([]byte(s), &student)
fmt.Println("反序列化后:", student) // 反序列化后: {韩信 24}
}
2.5 time包
- time.now():返回当前时间
- time.date():创建一个新的时间
time1.Sub(time2):计算两个时间的之间持续的时间- time.Parse(): 解析格式化字符串并返回相应的时间
-
time.Unix(): 计算当前时间的unix时间戳 -time.Format():格式化输出时间 -time.Year()/Month()/Day(): 年/月/日...
fmt.Println(time.Now() // 2022-03-27 18:04:59.433297 +0800 CST m=+0.000087933
t := time.Date(2022, 3, 27, 1, 25, 36, 0, time.UTC)
t2 := time.Date(2022, 3, 27, 2, 30, 36, 0, time.UTC)
fmt.Println(t) // 2022-03-27 01:25:36 +0000 UTC
fmt.Println(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute()) // 2022 March 27 1 25
fmt.Println(t.Format("2006-01-02 15:04:05")) // 2022-03-27 01:25:36
diff := t2.Sub(t)
fmt.Println(diff) // 1h5m0s
fmt.Println(diff.Minutes(), diff.Seconds()) // 65 3900
t3, err := time.Parse("2006-01-02 15:04:05", "2022-03-27 01:25:36")
if err != nil {
panic(err)
}
fmt.Println(t3 == t) // true
fmt.Println(now.Unix()) // 1648738080
2.6 strconv包
strconv.ParseFloat(字符串, 精度):将字符串转换为浮点数。strconv.ParseInt(字符串, X进制, 位数):将字符串转换为整数。
strconv.Atoi("123")
strconv.Atoi(字符串):将字符串转换为整数。
strconv.Atoi("AAA")
2.7 os包和os/exec包
os包是Go语言标准库中的一个包,提供了与操作系统交互的功能。它包含了处理文件、目录、环境变量、进程等操作的函数和类型。通过os包,我们可以执行文件操作、获取和设置环境变量、处理进程等。
os/exec包也是Go语言标准库中的一个包,用于执行外部命令。它提供了创建和执行外部命令的功能,可以在Go程序中调用其他可执行文件、脚本或系统命令。通过os/exec包,我们可以创建命令对象、设置命令的参数和环境变量、执行命令并获取其输出结果等操作。
os.Getenv()获取指定环境变量的值os.Setenv("AA", "BB"): 这个函数设置环境变量AA的值为BBexec.Command(命令名称, 命令所需参数).CombinedOutput()执行命令并返回命令的输出结果和错误信息os.Args是一个字符串切片,用于获取程序运行时的命令行参数os.Stdinos.Args是一个字符串切片,用于获取程序运行时的命令行参数