为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 golang 中使用运行时错误?

如何在 golang 中使用运行时错误?

Go
胡说叔叔 2021-07-10 14:03:46
我正在尝试从 3 个服务器下载一些东西。我的想法是如果第一台服务器关闭,它将使用第二台服务器。我注意到,如果第一台服务器已经关闭,它会创建一个运行时错误。我想知道如何使用这个错误,我需要的是这样的:if run time err!=nil{do something}我是 golang 的新手,希望有人能帮助我,谢谢
查看完整描述

2 回答

?
慕码人8056858

TA贡献1803条经验 获得超6个赞

为了详细说明 FUZxxl 的解释,go 区分了错误(可能出错的事情确实出错了)和异常(不可能出错的事情实际上出错了)。


区别有时可能很微妙(因为它依赖于“意外”),但它也可能比您在其他语言中看到的“一切都是例外”更清晰。


例如,考虑可能溢出的整数。一种可能性是将其视为“正常”行为,应适当处理:


func safe_add(x, y uint32) (uint32, error) {

    z := x + y

    if z < x || z < y {

        return 0, fmt.Errorf("Integer overflow")

    }

    return z, nil

}

另一个是考虑它“永远不会发生”,并panic在万一发生时在不太可能的情况下运行运行时:


func panic_add(x, y uint32) uint32 {

    z, err := safe_add(x, y)

    if err != nil {

        panic(err)

    }

    return z

}

(请注意,我在这里使用了我自己的“safe_add”,但您当然不必这样做)


主要区别在于您之后处理错误的方式。添加一个数字到它自己直到它溢出errors 给出:


func safeloop(u uint32) {

    var err error

    for {

        if u, err = safe_add(u, u); err != nil {

            fmt.Println(err)

            return

        } else {

            fmt.Println(u)

        }

    }

}

处理恐慌时使用recover内置函数:


func panicloop(u uint32) {

    defer func() {

        if err := recover(); err != nil {

            fmt.Println(err)

        }

    }()

    for {

        u = panic_add(u, u)

        fmt.Println(u)

    }

}

(操场上的完整示例)


请注意,恐慌版本有一个更简单的循环,因为您基本上从不期望任何错误并且从不检查错误。与此相反的是,处理恐慌的方法非常麻烦,即使是这样一个非常简单的例子。您defer是一个函数,它会recover在错误出现并脱离函数时调用并捕获错误。当你的代码变得更复杂,跟踪确切位置/恐慌是如何产生并作用于它因此可以成为很多比他们可能出现的地方检查错误,与更复杂result, err := func_which_may_fail(...)的图案。


您甚至可以在恐慌之间交替,恢复哪些返回错误,将错误转换为恐慌,......但这(可以理解)被认为是糟糕的设计。


go 博客上有一些关于错误处理和恐慌的好资源。该规范是读的好。


在您的情况下,由于您期望“服务器已关闭”是一种非常频繁的行为,因此您绝对应该error按照 FUZxxl 的建议行事,但我希望这可能对您(或其他人)了解错误处理的工作原理有用在去。


查看完整回答
反对 回复 2021-07-12
  • 2 回答
  • 0 关注
  • 213 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信