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

时间:2013-11-12 04:47:56

标签: http go runtime

我正在尝试从3台服务器下载内容。我的想法是,如果第一台服务器关闭,它将使用第二台服务器。我注意到,如果第一台服务器已经关闭,它会产生一个运行时错误。我想知道如何使用这个错误,我需要的是这样的:

if run time err!=nil{do something}

我是golang的新手,希望有人可以帮助我 谢谢

1 个答案:

答案 0 :(得分:8)

详细说明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',但你当然不必使用)

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

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)
    }
}

the playground上的完整示例)

请注意,恐慌版本有一个更简单的循环,因为你基本上从不指望出现任何问题,也从不检查错误。与此相对应的是,处理恐慌的方式非常麻烦,即使对于这样一个非常简单的例子也是如此。您defer一个函数将调用recover并在错误发生时捕获错误并突破该函数。当您的代码变得更加复杂时,准确地跟踪恐慌发生的位置和方式并相应地采取行动会比使用result, err := func_which_may_fail(...)检查可能出现的地方的错误更加复杂 更复杂图案。

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

在博客上的error handlingpanics上有一些很好的资源。 specs是一本很好的读物。

在您的情况下,正如您所期望的那样“服务器已关闭”是一种非常频繁的行为,您应该像{1}}那样采用FUZxxl建议的方式,但我希望这对您有用(或者其他)了解错误处理在Go中的工作原理。