欢迎来到代码驿站!

Golang

当前位置:首页 > 脚本语言 > Golang

golang panic及处理机制

时间:2022-03-05 09:51:29|栏目:Golang|点击:

一 panic机制

  panic会将这个异常不断向上抛出,直到有地方处理它,如果有处理,则不会再向上抛出。倘若没有处理,那么最终会导致main挂掉.

 golang虽然没有try catch机制,却有一种类似的recover机制,后续demo我们可以观测到它的用法和作用

二 实例   

2.1 main用recover

func main() {
    defer func() {
        if err := recover(); err != nil {
            log.Println("err:", err)
        }
    }()
    go test1()
    time.Sleep(time.Second * 3)
    panic(errors.New("stop test1"))
    log.Println("123")
    select {}
}
func test1() {
    for {
        tm := time.NewTicker(time.Second)
        select {
        case <-tm.C:
            log.Println("test1")
        }
    }
}

2.2 func用recover

func main() {
    defer func() {
        if err := recover(); err != nil {
            log.Println("err:", err)
        }
    }()
    go test1()
    time.Sleep(time.Second * 3)
    makeerr()
    log.Println("123")
    select {}
}
 
func test1() {
    for {
        tm := time.NewTicker(time.Second)
        select {
        case <-tm.C:
            log.Println("test1")
        }
    }
}
func makeerr() {
    defer func() {
        if err := recover(); err != nil {
            log.Println("makeerr:", err)
        }
    }()
    panic(errors.New("stop"))
}

此时我们在func中用recover,那么挂掉的只是func,他不会抛到main中,所以main能继续运行,继而main开辟的go test1也能继续运行

2.3 func用recover且开创goroutine

func main() {
    defer func() {
        if err := recover(); err != nil {
            log.Println("err:", err)
        }
    }()
 
    time.Sleep(time.Second * 3)
    makeerr()
    log.Println("123")
    select {}
}
 
func test1() {
    for {
        tm := time.NewTicker(time.Second)
        select {
        case <-tm.C:
            log.Println("test1")
        }
    }
}
func makeerr() {
    defer func() {
        if err := recover(); err != nil {
            log.Println("makeerr err:", err)
        }
    }()
    go test1()
    panic(errors.New("stop test"))
}

我们发现,func虽然挂掉了,但是他开创的go没挂掉,因为即使是这个函数退出了,新开的协程是相当于基于main下的一个子程,只要main不退出,他依然会“存活”

2.4 goroutine中panic

func main() {
    defer func() {
        if err := recover(); err != nil {
            log.Println("err:", err)
        }
    }()
    go test1()
    time.Sleep(time.Second * 3)
    log.Println("123")
    select {}
}
func test1() {
    log.Println("test1 start")
    panic(errors.New("stop test1"))
    log.Println("test1 end")
}

协程中如果没recover,那么error就会抛向main,main就会挂掉,从而没有执行到后面的log打印。

---> 这种情况,main中做defer recover是没用的

2.5 func1内嵌func2中panic且func2做处理

func main() {
    test1()
    time.Sleep(time.Second * 3)
    log.Println("123")
}
func test1() {
    log.Println("test1 start")
    test2()
    log.Println("test1 end")
}
func test2() {
    defer func() {
        if err := recover(); err != nil {
            log.Println("test2 err:", err)
        }
    }()
    log.Println("test2 start")
    panic(errors.New("stop test2"))
    log.Println("test2 end")
}

2.6 func1内嵌func中panic且func1做处理

func main() {
    test1()
    time.Sleep(time.Second * 3)
    log.Println("123")
}
func test1() {
    defer func() {
        if err := recover(); err != nil {
            log.Println("test? err:", err)
        }
    }()
    log.Println("test1 start")
    test2()
    log.Println("test1 end")
}
func test2() {
    log.Println("test2 start")
    panic(errors.New("stop test2"))
    log.Println("test2 end")
}

func2异常,执行终止,向调用者func1抛出进而本身退出,func1得到异常,执行终止,本身退出时recover进行处理,从而保活了main

上一篇:深入解析golang中的标准库flag

栏    目:Golang

下一篇:Gin框架之参数绑定的实现

本文标题:golang panic及处理机制

本文地址:http://www.codeinn.net/misctech/195323.html

推荐教程

广告投放 | 联系我们 | 版权申明

重要申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ:914707363 | 邮箱:codeinn#126.com(#换成@)

Copyright © 2020 代码驿站 版权所有