dongqiao8502 2015-11-08 14:34
浏览 32
已采纳

进行错误处理,使事情变干的惯用方式是什么

Consider the following example program which is primitive stack implementation in Go:

package main

import "fmt"
import "errors"

const MAX_SIZE = 10

var a [10]int
var top int = -1

func main() {
    printStack()
    push(1)
    printStack()
    push(23)
    printStack()
    pop()
    push(2)
    push(24)
    push(56)
    push(87)
    push(97)
    push(47)
    push(37)
    push(31)
    push(69)
    printStack()
    push(75)
    println("Top element is", getTop())
}

func push(x int) (int, error) {
    if top >= (MAX_SIZE - 1) {
        return 0, errors.New("Error: Prevented Stackoverflow. Stack full")
    }
    top += 1
    a[top] = x
    return 0, nil
}

func pop() {
    top -= 1
}

func getTop() int {
    return a[top]
}

func printStack() {
    fmt.Println(top+1, "Stack: ", a, "Top", top)
}

Now, I read Error handling and Go & it seems the above way of returning multiple values is the way to handle errors in go.

But what I don't understand is that does do gophers check of errors on every statement? Coming from other languages this concept it bit hard for me to grok. So the question is

  1. What is the idiomatic way of handling errors in above problem?
  2. Is considered a bad practice if I don't check for errors? if yes, then I am supposed to check the output of push() everytime I call it?

Basically what I want to know if how would a experienced gopher do error handling in the above program?

Play URL: https://play.golang.org/p/_AnZLvY-28

[Update] Added a real-world program where I fetch data from database & output to json. http://play.golang.org/p/dDApCYprjU

  • 写回答

1条回答 默认 最新

  • dourou9477 2015-11-08 15:18
    关注

    Yes, the idiomatic way to produce errors is to return multiple values. The idiomatic way to handle errors is this:

    val, err := myFunc()
    if err != nil {
        // do something with err
    }
    
    // do something with val
    

    At the end of the day it's a judgement call, but it's almost always good practice to handle errors. The code you're writing is also a bit unusual, you normally don't have 10 calls to the same function back-to-back, so the verbose error handling you'd have to do is more a result of the original code. For instance, you could use a loop:

    for _, num := range []int{2, 24, 56, 87, 97, 47, 37, 31, 69} {
        _, err := push(num)
        if err != nil {
            panic(err)
        }
    }
    

    You have some other things that are more problematic than not handling the push errors though. One minor thing is there is no reason for push to always return 0, why not only have it return an error, instead of an int and an error? The bigger problem is that pop keeps decrementing top, and getTop just accesses a[top], so you can easily get a runtime panic if top becomes negative from having popped too much. You probably want some error handling or other safeguards in your pop and getTop functions.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题