day7函数 Panic机制 recover机制 练习5.19

master
独孤伶俜 2022-12-12 01:12:00 +08:00
parent 010c5bc593
commit 4cb65ecbac
3 changed files with 100 additions and 0 deletions

View File

@ -0,0 +1,31 @@
package main
import (
"fmt"
"os"
"runtime"
)
func main() {
// 当发生 panic时,会立即执行该GorouTime的defer函数,
// 然后程序崩溃, 并输出日志信息
// 日志信息包括panic的文字描述, 函数名, 报错行号, 堆栈信息
// 勤奋的程序员认为任何崩溃都表明代码中存在漏洞,
// 所以对于大部分漏洞我们应该使用Go提供的错误机制
// 而不是panic尽量避免程序的崩溃。
defer printStack()
f(3)
}
func printStack() {
var buf [4096]byte
n := runtime.Stack(buf[:], false)
os.Stdout.Write(buf[:n])
}
func f(x int) {
fmt.Printf("f(%d)\n", x+0/x) // panics if x == 0
defer fmt.Printf("defer %d\n", x)
f(x - 1)
}

View File

@ -0,0 +1,27 @@
package main
import (
"fmt"
"log"
)
func main() {
ret := practice()
fmt.Println(ret)
}
func practice() (result int) {
defer func() {
if r := recover(); r != nil {
log.Println("Recovered in f", r)
// 断言, 参考第七章7.10节的内容
// see: https://zhuanlan.zhihu.com/p/149015320
// 具体作用为检查接口中是否包含int类型的值, 并返回该值
// panic接受一个类型为any的参数
// 该参数的any类型实际为一个空接口
// 参考Go安装目录 /src/builtin/builtin.go:95 :252
result = r.(int) // 断言 int
}
}()
panic(34)
}

View File

@ -0,0 +1,42 @@
package main
import (
"Study/src/study/day7Function/HtmlTools"
"fmt"
"golang.org/x/net/html"
)
func main() {
// 定义该defer语句的函数发生了panic异常recover会使程序从panic中恢复
t, _ := soleTitle(HtmlTools.GetHtml())
fmt.Println(t)
}
// soleTitle returns the text of the first non-empty title element
// in doc, and an error if there was not exactly one.
func soleTitle(doc *html.Node) (title string, err error) {
type bailout struct{}
defer func() {
switch p := recover(); p {
case nil: // no panic
case bailout{}: // "expected" panic
err = fmt.Errorf("multiple title elements")
default:
panic(p) // unexpected panic; carry on panicking
}
}()
// Bail out of recursion if we find more than one nonempty title.
HtmlTools.ForEachNode(doc, func(n *html.Node) {
if n.Type == html.ElementNode && n.Data == "title" &&
n.FirstChild != nil {
if title != "" {
panic(bailout{}) // multiple titleelements
}
title = n.FirstChild.Data
}
}, nil)
if title == "" {
return "", fmt.Errorf("no title element")
}
return title, nil
}