doucong6884 2013-11-12 04:47
浏览 86
已采纳

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

I am trying to download something from 3 servers. My idea is if the first server is closed,it will use the second server. I noticed,if the first server has been closed, it will created a run time error.I want to know how to use this error,what i need is like this:

if run time err!=nil{do something}

i am new to golang,hope someone can help me thank you

  • 写回答

2条回答 默认 最新

  • douzhicong5965 2013-11-12 11:44
    关注

    To elaborate on what FUZxxl explained, go makes a distinction between an error (something which could go wrong indeed went wrong) and an exception (something which could not possibly go wrong actually went wrong).

    The distinction can sometimes be subtle (as it relies on what is 'unexpected'), but it can also be clearer than the 'everything is an exception' that you see in other languages.

    For instance, consider integers which might overflow. One possibility is to consider it a 'normal' behaviour, which should be handled appropriately:

    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
    }
    

    Another is to consider it 'never happens' and have the runtime panic in the unlikely case when it happens against all odds:

    func panic_add(x, y uint32) uint32 {
        z, err := safe_add(x, y)
        if err != nil {
            panic(err)
        }
        return z
    }
    

    (Note that I use my own 'safe_add' here, but you don't have to of course)

    The main difference is in the way you handle the error afterwards. Adding a number to itself until it overflows with errors gives:

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

    While handling panics uses the recover built-in function:

    func panicloop(u uint32) {
        defer func() {
            if err := recover(); err != nil {
                fmt.Println(err)
            }
        }()
        for {
            u = panic_add(u, u)
            fmt.Println(u)
        }
    }
    

    (full examples on the playground)

    Note that the panic version has a much simpler loop, as you basically never expect anything to go wrong and never check for errors. The counterpart for this is that the way to handle panics is quite cumbersome, even for a very simple example like this. You defer a function which will call recover and capture the error when it arises and breaks out of the function. When your code becomes more complex, tracking exactly where/how the panic arose and acting on it accordingly can become much more complex than checking for errors in places where they could arise, with the result, err := func_which_may_fail(...) pattern.

    You can even alternate between panics, recover which return errors, errors converted to panics, ... but this is (understandably) considered poor design.

    There are some good resources on error handling and panics on the go blog. The specs is a good read to.

    In your case, as you expect 'the server is closed' to be a pretty frequent behaviour, you should definitely go the error way, as FUZxxl suggested, but I hope this might be useful to you (or others) to understand how error handling works in Go.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 网络设备配置与管理这个该怎么弄
  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器