golang的log.Fatal()和panic()函數(shù)的區(qū)別

golang的log.Fatal()和panic()函數(shù)的區(qū)別

在講兩者區(qū)別之前我們先看一下os.Exit()函數(shù)的定義:

func Exit(code int)

Exit causes the current program to exit with the given status code.
Conventionally, code zero indicates success, non-zero an error.
The program terminates immediately; deferred functions are not run.

注意兩點(diǎn):

  1. 應(yīng)用程序馬上退出。
  2. defer函數(shù)不會(huì)執(zhí)行。

再來看log.Fatal函數(shù)定義

func Fatal(v ...interface{})

Fatal is equivalent to Print() followed by a call to os.Exit(1).

看源代碼:go/src/log/log.go

// Fatal is equivalent to l.Print() followed by a call to os.Exit(1).
func (l *Logger) Fatal(v ...interface{}) {
    l.Output(2, fmt.Sprint(v...))
    os.Exit(1)
}

總結(jié)起來log.Fatal函數(shù)完成:

  1. 打印輸出內(nèi)容
  2. 退出應(yīng)用程序
  3. defer函數(shù)不會(huì)執(zhí)行

和os.Exit()相比多了第一步。

再來看內(nèi)置函數(shù)panic()函數(shù)定義:

// The panic built-in function stops normal execution of the current
// goroutine. When a function F calls panic, normal execution of F stops
// immediately. Any functions whose execution was deferred by F are run in
// the usual way, and then F returns to its caller. To the caller G, the
// invocation of F then behaves like a call to panic, terminating G's
// execution and running any deferred functions. This continues until all
// functions in the executing goroutine have stopped, in reverse order. At
// that point, the program is terminated and the error condition is reported,
// including the value of the argument to panic. This termination sequence
// is called panicking and can be controlled by the built-in function
// recover.
func panic(v interface{})

注意幾點(diǎn):

  1. 函數(shù)立刻停止執(zhí)行 (注意是函數(shù)本身,不是應(yīng)用程序停止)
  2. defer函數(shù)被執(zhí)行
  3. 返回給調(diào)用者(caller)
  4. 調(diào)用者函數(shù)假裝也收到了一個(gè)panic函數(shù),從而
    4.1 立即停止執(zhí)行當(dāng)前函數(shù)
    4.2 它defer函數(shù)被執(zhí)行
    4.3 返回給它的調(diào)用者(caller)
  5. ...(遞歸重復(fù)上述步驟,直到最上層函數(shù))
    應(yīng)用程序停止。
  6. panic的行為

簡(jiǎn)單的總結(jié)panic()就有點(diǎn)類似java語言的exception的處理,因而panic的行為和java的exception處理行為就非常類似,行為結(jié)合catch,和final語句塊的處理流程。

下面給幾個(gè)例子:

例子1:log.Fatal

package main

import (
    "log"
)

func foo() {
    defer func () { log.Print("3333")} ()
    log.Fatal("4444")
}

func main() {
    log.Print("1111")
    defer func () { log.Print("2222")} ()
    foo()
    log.Print("9999")
}

運(yùn)行結(jié)果:

$ go build && ./main
2018/08/20 17:48:44 1111
2018/08/20 17:48:44 4444

可見defer函數(shù)的內(nèi)容并沒有被執(zhí)行,程序在log.Fatal(...)處直接就退出了。

例子2:panic()函數(shù)

package main

import (
    "log"
)

func foo() {
    defer func () { log.Print("3333")} ()
    panic("4444")
}

func main() {
    log.Print("1111")
    defer func () { log.Print("2222")} ()
    foo()
    log.Print("9999")
}

運(yùn)行結(jié)果:

$ go build && ./main
2018/08/20 17:49:28 1111
2018/08/20 17:49:28 3333
2018/08/20 17:49:28 2222
panic: 4444

goroutine 1 [running]:
main.foo()
        /home/.../main.go:9 +0x55
main.main()
        /home/.../main.go:15 +0x82

可見所有的defer都被調(diào)用到了,函數(shù)根據(jù)父子調(diào)用關(guān)系所有的defer都被調(diào)用直到最上層。
當(dāng)然如果其中某一層函數(shù)定義了recover()功能,那么panic會(huì)在那一層函數(shù)里面被截獲,然后由recover()定義如何處理這個(gè)panic,是丟棄,還是向上再拋出。(是不是和exception的處理機(jī)制一模一樣呢?)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Lua 5.1 參考手冊(cè) by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 14,235評(píng)論 0 38
  • 函數(shù)和對(duì)象 1、函數(shù) 1.1 函數(shù)概述 函數(shù)對(duì)于任何一門語言來說都是核心的概念。通過函數(shù)可以封裝任意多條語句,而且...
    道無虛閱讀 4,926評(píng)論 0 5
  • 如你所知,高質(zhì)量的啪啪,應(yīng)該換幾個(gè)姿勢(shì)?同理,高質(zhì)量的時(shí)間買賣,應(yīng)該換哪些姿勢(shì)? 1. 單份地出售自己的時(shí)間。 如...
    拉布拉多華安閱讀 2,148評(píng)論 0 1
  • 這里講兩個(gè)故事,我的兩個(gè)工薪階層的朋友在房市中投資的事,以此作為“事后諸葛亮”看看他們是如何想的。 第一個(gè)朋友...
    程子懿閱讀 370評(píng)論 1 0
  • 我知道,自己不是個(gè)聰明人,只是我以為,自己是個(gè)認(rèn)真的人、是個(gè)態(tài)度端正的人。 認(rèn)真對(duì)待每一份感情,認(rèn)真對(duì)待每一份工作...
    喵貝_4f3f閱讀 222評(píng)論 0 1

友情鏈接更多精彩內(nèi)容