Go-panic-defer-recover那些事

  • 如果发生了 panic, 程序就会抛出运行时异常, 并退出程序
  • panic 有可能是非法操作导致的, 也可以主动通过 panic() 抛出
  • defer 后的函数会在上一层的函数执行完成后执行
  • recover 可以恢复 panic, 并不退出程序
  • recover 要配合 defer 一起使用

上代码, 自己品

package main

import "fmt"

func main() {
	list := []int{1, 2, 3}
	fmt.Println(list[len(list)]) // panic: runtime error: index out of range [3] with length 3
}
package main

import (
	"fmt"
)

type Person struct {
	Name string
}

func main() {
	var p *Person

	// 编译会出错, 但是运行的时候会出现异常. 所以使用指针的时候要特别注意
	fmt.Println(p.Name)
}

/*
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x108a136]
*/
package main

import (
	"fmt"
)

type Person struct {
	name string
}

func (self *Person) Name() string {
	return self.name
}

func (self *Person) String() {
	fmt.Println("Person")
}

func main() {
	var p *Person

	fmt.Println(p) // nil

	// 可以调用成员方法, 但是成员方法不可以使用属性
	p.String() // Person

	// 可以调用成员方法, 但是成员方法不可以使用属性
	fmt.Println(p.Name()) // panic: runtime error: invalid memory address or nil pointer dereference
}
package main

import (
	"fmt"
)

func main() {
	list := []int{1, 2, 3}

	// 不会输出错误, 因为主 goroutine 退出的时候, 函数里面的语句还没有执行
	go func() {
		fmt.Println(list[len(list)])
	}()
}
package main

import (
	"fmt"
	"time"
)

func main() {
	list := []int{1, 2, 3}

	// 其他 goroutine 出现 panic 的时候, 主 goroutine 也会退出
	go func() {
		fmt.Println(list[len(list)])
	}()

	for i:= 0; i < len(list); i++ {
		fmt.Println(list[i])
		time.Sleep(time.Second)
	}
}

/*
1
panic: runtime error: index out of range [3] with length 3

goroutine 6 [running]:
main.main.func1()
 */
package main

import (
	"fmt"
)

func main() {
	// 只要这一行执行到了, 函数执行完成后, 都会执行 defer 后面这个函数
	defer func() {
		fmt.Println("end")
	}()

	panic("发生了错误")
}

/*
end
panic: 发生了错误
*/
package main

import (
	"fmt"
)

func main() {
	// 后面的语句不会执行
	panic("发生了错误")

	// 这一行没有执行, 所以 defer 后面的函数也没有执行
	defer func() {
		fmt.Println("end")
	}()
}

/*
panic: 发生了错误
*/
package main

import "fmt"

func valid() {
	panic("发生了错误")
}

func main() {
	valid()
	// 发生运行时异常, 无法执行以下语句
	fmt.Println("end")
}

/*
panic: 发生了错误

goroutine 1 [running]:
main.valid(...)
*/
package main

import "fmt"

func valid() {
	defer func() {
		p := recover()
		fmt.Printf("错误: %s\n", p)
	}()

	panic("发生了错误")

	fmt.Println("valid end")
}

func main() {
	valid()
	// valid() 捕获了运行时异常, 以下语句还是可以继续执行
	fmt.Println("end")
}

/*
错误: 发生了错误
end
*/
package main

import "fmt"

func valid() {
	defer func() {
		p := recover()
		fmt.Printf("错误: %s\n", p)
		panic("recover 后发生错误")
	}()

	panic("发生了错误")

	fmt.Println("valid end")
}

func main() {
	valid()
	// valid() 捕获了运行时异常, 以下语句还是可以继续执行
	fmt.Println("end")
}

/*
错误: 发生了错误
panic: 发生了错误 [recovered]
        panic: recover 后发生错误

goroutine 1 [running]:
main.valid.func1()
*/
package main

import "fmt"

func valid() {
	defer func() {
		p := recover()
		fmt.Printf("错误: %s\n", p)

		defer func() {
			p := recover()
			fmt.Printf("错误: %s\n", p)
		}()
		panic("recover 后发生错误")
	}()

	panic("发生了错误")

	fmt.Println("valid end")
}

func main() {
	valid()
	// valid() 捕获了运行时异常, 以下语句还是可以继续执行
	fmt.Println("end")
}

/*
错误: 发生了错误
错误: recover 后发生错误
end
*/
package main

import "fmt"

func main() {
	defer func() {
		p := recover()
		fmt.Printf("错误: %v\n", p)
	}()
}

/*
错误: <nil>
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值