公众号merlinsea
- 异常
- defer - panic / error- recover来处理异常
- panic表示发生一个致命的错误,通常是如果程序发生panic应该立即停止执行,比如项目中初始化中间件的时候发生错误或者读取配置文件发生错误的时候就应该报panic错误,这种错误不需要去捕获处理
- error表示发生了一个不太致命的错误,通常这种错误是程序员自定义的错误,并且希望调用方捕获这种错误以后进行处理,处理完继续执行后续代码。
- defer - panic / error- recover来处理异常
func test() {
//使用defer + recover 来捕获和处理异常
defer func() {
err := recover() // recover()内置函数,可以捕获到异常
if err != nil { // 说明捕获到错误
fmt.Println("err=", err)
//这里就可以将错误信息发送给管理员....
fmt.Println("发送邮件给admin@sohu.com~")
}
}()
num1 := 10
num2 := 0
res := num1 / num2
fmt.Println("res=", res)
}
//函数去读取以配置文件init.conf的信息
//如果文件名传入不正确,我们就返回一个自定义的错误
func readConf(name string) (err error) {
if name == "config.ini" {
//读取...
return nil
} else {
//返回一个自定义错误
return errors.New("读取文件错误..")
}
}
func test02() {
err := readConf("config2.ini")
if err != nil {
//如果读取文件发送错误,就输出这个错误,并终止程序
panic(err)
}
fmt.Println("test02()继续执行....")
}
func main() {
//测试
test()
for {
fmt.Println("main()下面的代码...")
time.Sleep(time.Second)
}
//测试自定义错误的使用
//
//test02()
//fmt.Println("main()下面的代码...")
}- 切片slice
- slice的本质上是一个结构体,这个结构体中包含三个部分
- slice的本质上是一个结构体,这个结构体中包含三个部分
- 第一个部分是ptr指针,指向某一块连续空间的首地址
- 第二个部分是len长度,表示这个切片取这块连续空间实际的长度
- 第三个部分是cap容量,这个容量通常是len的两倍,避免由于平凡加入元素而不断扩容。【相当于预先分配更多的空间】
- 第一个部分是ptr指针,指向某一块连续空间的首地址
- slice[0] 相当于取到了指向空间的值,因此修改slice[0]以后,其实际指向的空间内容也会变化。
- slice := intArr[1:3] ,左闭右开 可以通过这种方法将一个数组的某段区间的首地址赋值给slice,后续如果修改了slice所指向空间的内容, 数组的值也会修改
- 对切片slice进行append操作会返回一个新的切片地址!
- slice[0] 相当于取到了指向空间的值,因此修改slice[0]以后,其实际指向的空间内容也会变化。
func main() {
//演示切片的基本使用
var intArr [5]int = [...]int{1, 22, 33, 66, 99}
//声明/定义一个切片
//slice := intArr[1:3]
//1. slice 就是切片名
//2. intArr[1:3] 表示 slice 引用到intArr这个数组
//3. 引用intArr数组的起始下标为 1 , 最后的下标为3(但是不包含3)
slice := intArr[1:3]
fmt.Println("intArr=", intArr)
fmt.Println("slice 的元素是 =", slice) // 22, 33
fmt.Println("slice 的元素个数 =", len(slice)) // 2
fmt.Println("slice 的容量 =", cap(slice)) // 切片的容量是可以动态变化
fmt.Printf("intArr[1]的地址=%p\n", &intArr[1])
fmt.Printf("slice[0]的地址=%p slice[0==%v\n", &slice[0], slice[0])
slice[1] = 34
fmt.Println()
fmt.Println()
fmt.Println("intArr=", intArr)
fmt.Println("slice 的元素是 =", slice) // 22, 33
}- leetcode中字母异位词分组
- 对string进行排序,首先将string转为byte切片,然后对切片进行排序,排序以后再将切片转回string类型
- 对string进行排序,首先将string转为byte切片,然后对切片进行排序,排序以后再将切片转回string类型
func groupAnagrams(strs []string) [][]string {
var mp map[string][]string = make(map[string][]string)
for _,str := range strs {
slice := []byte(str) // string转切片
sort.SliceStable(slice, func(i, j int) bool {
return slice[i] < slice[j]
})
key := string(slice)
_,ok := mp[key]
if !ok {
// 第一次遇见这个字符串,因此可以先构建空间
mp[key] = make([]string,0)
mp[key] = append(mp[key],str)
}else{
// list = append(list,str) 假设获取了mp[key] = list 错误,不会影响到map本身,核心是append本身会创建一个新的空间返回
mp[key] = append(mp[key],str)
}
}
lists := make([][]string,0)
for _,list := range mp{
lists = append(lists,list)
}
return lists
}- 算法训练营永久vip学习班【目前主要采用的编程语言是go语言】
- 算法训练营永久vip学习班【目前主要采用的编程语言是go语言】
- golang算法训练营报名详情如下,快加入我们吧,永久授课和学习,我自己负责的课程会一直维护下去~,后面还会分享gorm,gin,grpc等框架的学习~
奔跑的小梁,公众号:梁霖编程工具库算法训练营golang专题刷题来啦!!!