3

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

if run time err!=nil{do something}

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

4

2 回答 2

9

为了详细说明 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)
    }
}

(操场上的完整示例)

请注意,panic 版本的循环要简单得多,因为您基本上永远不会期望会出错,也永远不会检查错误。与此相对的是处理恐慌的方法非常麻烦,即使对于像这样的非常简单的示例也是如此。您defer是一个函数,它将recover在错误出现并脱离函数时调用并捕获错误。当您的代码变得更加复杂时,准确跟踪恐慌发生的位置/方式并据此采取行动可能使用模式检查可能出现的错误的地方要复杂得多result, err := func_which_may_fail(...)

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

go 博客上有一些关于错误处理恐慌的好资源。规格是一个很好的阅读。

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

于 2013-11-12T11:44:02.970 回答
1

当你做一些可能出错的事情时,你会得到一个error对象。

bytes, err = stream.Read(buffer)

要检查您尝试的操作是否真的出错了,请将error对象与nil. nil表示没有发生错误。如果错误不是nil,您可以对其进行处理。

if err != nil {
    // insert error handling here
}
于 2013-11-12T07:57:47.290 回答