Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 用围棋中的包装器恢复恐慌_Go - Fatal编程技术网

Go 用围棋中的包装器恢复恐慌

Go 用围棋中的包装器恢复恐慌,go,Go,我遇到了以下使用包装器管理从恐慌中恢复的代码。我知道恐慌不会在goroutine中传播,它们必须独立管理,所以它需要在恐慌发生的goroutine中处理 package main import ( "fmt" "time" ) func main() { go Wrap(test)() time.Sleep(time.Second) fmt.Println("HELLO") } func t

我遇到了以下使用包装器管理从恐慌中恢复的代码。我知道恐慌不会在goroutine中传播,它们必须独立管理,所以它需要在恐慌发生的goroutine中处理

package main

import (
    "fmt"
    "time"
)

func main() {
    go Wrap(test)()
    time.Sleep(time.Second)
    fmt.Println("HELLO")
}

func test() {
    panic("PANIC")
}

func Wrap(f func()) func() {
    return func() {
        defer func() {
            if r := recover(); r != nil {
                fmt.Printf("RECOVERED - %v\r\n", r)
            }
        }()
        f()
    }
}

func WrapWithSignal(f func(chan bool), signal chan bool) func() {
    return func() {
        defer func() {
            if r := recover(); r != nil {
                fmt.Printf("RECOVERED - %v\r\n", r)
                signal <- false
            }
        }()
        f(signal)
    }
}
主程序包
进口(
“fmt”
“时间”
)
func main(){
去包裹(测试)()
时间。睡眠(时间。秒)
fmt.Println(“你好”)
}
func测试(){
恐慌(“恐慌”)
}
func Wrap(f func())func(){
返回func(){
延迟函数(){
如果r:=recover();r!=nil{
fmt.Printf(“已恢复-%v\r\n”,r)
}
}()
f()
}
}
func幽灵信号(f func(chan bool),signal chan bool)func(){
返回func(){
延迟函数(){
如果r:=recover();r!=nil{
fmt.Printf(“已恢复-%v\r\n”,r)

signal在实现长时间运行的流程时,某些代码路径可能会导致死机。这通常适用于未初始化的映射和指针,以及在验证不充分的用户输入情况下的零除问题

在这些情况下,程序完全崩溃通常比恐慌本身严重得多,因此捕捉和处理恐慌是有帮助的

在大多数web应用程序中,常见的情况是捕捉恐慌并在恐慌发生时发出http.InternalServerError消息

在recover中,您基本上可以做任何您想做的事情,尽管发出日志是很常见的

1)带信号的包裹可用于从恐慌中恢复,并向给定的布尔通道发送信号。

warp with signal函数实现了wrap模式,可用于包装信号通道,并在发生死机时向通道发送事件。在这种情况下,如果未调用recover,则会出现死锁

package main

import (
    "errors"
    "fmt"
    "math/rand"
    "time"
)

func main() {
    signal:= make(chan bool)
    go WrapWithSignal(play, signal)()

    if <-signal{
        fmt.Println("Congratulations, you win!")
        return
    }

    fmt.Println("You died.")
}

func play(signal chan bool){
    fmt.Println("Playing russian roulette")
    rand.Seed(time.Now().UnixNano())

    if rand.Intn(2) == 1{
        panic(errors.New("got a bullet"))
    }

    signal <- true
}
主程序包
进口(
“错误”
“fmt”
“数学/兰德”
“时间”
)
func main(){
信号:=制造(chan bool)
go WrapWith信号(播放,信号)()

如果相同:从恐慌中恢复。它也会在提供的频道上发送false。这里没有什么特别的内容。另外一个注意事项:如果你是新手,请远离恢复。新手往往认为恢复是经常发生的事情。事实并非如此。它适用于一些罕见的情况。我希望这能回答2:包装函数有多复杂并不重要离子是因为你没有这样做。太好了,谢谢你的解释,我不会使用恢复