去错误处理,什么是使事情变干的惯用方法

标签 go

考虑以下示例程序,它是 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)
}

现在,我阅读了 Error handling and Go &似乎上面返回多个值的方式是处理错误的方式。

但我不明白的是,地鼠会检查每条语句的错误吗?来自其他语言的这个概念让我很难理解。所以问题是

  1. 在上述问题中处理错误的惯用方法是什么?
  2. 如果我不检查错误会被认为是一种不好的做法吗?如果是,那么我应该在每次调用时检查 push() 的输出吗?

基本上我想知道的是,如果有经验的 gopher 在上面的程序中会如何进行错误处理?

播放网址:https://play.golang.org/p/_AnZLvY-28

[更新] 添加了一个真实世界的程序,我从数据库中获取数据并输出到 json。 http://play.golang.org/p/dDApCYprjU

最佳答案

是的,产生错误的惯用方式是返回多个值。处理错误的惯用方法是这样的:

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

// do something with val

归根结底,这是一个判断电话,但处理错误几乎总是好的做法。您正在编写的代码也有点不寻常,您通常不会对同一个函数连续调用 10 次,因此您必须执行的冗长错误处理更多是原始代码的结果。例如,您可以使用一个循环:

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

不过,您还有其他一些比不处理推送错误更成问题的事情。一件小事是 push 没有理由总是返回 0,为什么它不仅返回一个错误,而不是一个 int 和一个错误?更大的问题是 pop 不断递减 top,而 getTop 只是访问 a[top],所以你可以如果 top 由于 pop 太多而变得消极,很容易导致运行时 panic 。您可能需要在 popgetTop 函数中进行一些错误处理或其他保护措施。

关于去错误处理,什么是使事情变干的惯用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33595102/

相关文章:

go - 更正我的 goroutines 的实现

go - 定义自定义HTML字符串化的最简单方法是什么?

go - Golang gorm URL转义了

file - go - 使用 struct 读取二进制文件

string - 查找 []byte slice 中所有出现的字符串

go - 允许在结构中使用复合作为函数参数

linux - 从 Go 访问 Linux 网络 API

go - Go中如何将 slice 组合成一个元组 slice (实现python `zip`函数)?

go - 如何管理使用 Win32 API(记事本、Word、Outlook、Chrome 等)打开的应用程序窗口

sockets - golang的net.Conn.Read怎么读到什么时候停止?