day7函数 Panic机制 recover机制 练习5.19
parent
010c5bc593
commit
4cb65ecbac
|
@ -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)
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue