- 如果发生了 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>
*/