Golang中是否应该始终处理函数错误?

Golang中是否应该始终处理函数错误? 假设我们有一个"非常安全"的函数:

func ThisFunctionIsNotGoingToFail_Probably(...) error {
   // very secure code
}

这个函数不太可能失败。但在某些特定情况下它可能会失败(例如,在外星人入侵期间)。直接这样写是否正确:

ThisFunctionIsNotGoingToFail_Probably(…);

还是应该这样写?

if err := ThisFunctionIsNotGoingToFail_Probably; err != nil {
    panic(err)
}

谢谢。


更多关于Golang中是否应该始终处理函数错误?的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

当程序出现错误时,它应该如何运行?即使函数执行失败,它是否仍能继续执行原有操作?如果是,你可以忽略错误。但我建议至少记录错误信息。因此推荐采用第二种形式。

更多关于Golang中是否应该始终处理函数错误?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


首先,你不应该调用 panic 函数。它仅用于真正异常的情况。通常,你只需通过记录日志或优雅终止程序等方式来处理错误。

此外,无论你的函数属于本地包、外部包还是其他情况,你都应该始终处理错误。

关于你的问题:

例如,像 strconv.Atoi 这样的函数在发生错误时通常返回 0。因此,有时你可能会忽略处理它。或者,例如 fmt.Println 也会返回错误,但我们通常不处理它。

好的,这门语言让我思考。这是件好事。以下是我的方法。

  1. 第一种情况:该函数属于某个项目。在这种情况下,它不应该返回任何错误。相反,函数应该处理自己的错误:
// 该函数属于一个项目
func ThisFunctionIsNotGoingToFail_Probably(...) {
    // 非常安全的代码(...可能)
    if err != nil {
        log.Fatal(error)
    }
}

// ...然后我们可以从项目的其他地方安全地使用它
ThisFunctionIsNotGoingToFail_Probably(...)
...
ThisFunctionIsNotGoingToFail_Probably(...)
  1. 第二种情况:前述函数属于外部库。在这种情况下,函数应该返回错误,我们应该处理它:
// 该函数在外部库中声明
func ThisFunctionIsNotGoingToFail_Probably(...) error {
    // 非常安全的代码
}

// ...我们在我们的项目或库中处理错误
if err := ThisFunctionIsNotGoingToFail_Probably(...) {
    panic(error) // 或 log.Fail(error) 等...
}

这基本上就是我打算遵循的规则。 抱歉我的西班牙式英语 🙂

在Go语言中,无论函数失败的概率有多低,都应该始终处理错误。忽略错误返回值是糟糕的实践,即使你认为函数"不太可能失败"。

在你的例子中,直接调用函数而不处理错误:

ThisFunctionIsNotGoingToFail_Probably(...)

这是不正确的,因为编译器会报错:函数返回了错误值但没有被使用。

正确的做法是至少检查并处理错误。你提供的第二个方案:

if err := ThisFunctionIsNotGoingToFail_Probably(...); err != nil {
    panic(err)
}

这是可以接受的,特别是当错误确实表示程序无法继续运行的严重情况时。

不过,更地道的Go错误处理方式包括:

  1. 返回错误给调用者
if err := ThisFunctionIsNotGoingToFail_Probably(...); err != nil {
    return err
}
  1. 记录错误并继续(如果适用):
if err := ThisFunctionIsNotGoingToFail_Probably(...); err != nil {
    log.Printf("Unexpected error: %v", err)
    // 可能继续执行其他逻辑
}
  1. 使用panic(仅适用于真正不可恢复的错误):
if err := ThisFunctionIsNotGoingToFail_Probably(...); err != nil {
    panic(fmt.Sprintf("Critical failure: %v", err))
}

考虑这个实际例子:

func GetEnvironmentVariable(key string) (string, error) {
    value := os.Getenv(key)
    if value == "" {
        return "", fmt.Errorf("environment variable %s not set", key)
    }
    return value, nil
}

// 正确的使用方式
func main() {
    apiKey, err := GetEnvironmentVariable("API_KEY")
    if err != nil {
        log.Fatal("Failed to get API key:", err)
    }
    fmt.Println("API Key:", apiKey)
}

即使在"不太可能失败"的情况下,处理错误也能确保代码的健壮性和可维护性。未处理的错误可能导致程序在意外的地方崩溃,或者产生难以调试的异常行为。

回到顶部