返回并处理错误

处理错误是编写健壮代码的关键功能。在本节中,您将向 greetings 模块添加一些代码来返回错误,然后在调用方中处理它。

  1. 在 greetings/greetings.go 中,添加下面高亮显示的代码。

    如果您不知道要向谁致意,就没有意义返回问候语。如果名称为空,则向调用方返回错误。将以下代码复制到 greetings.go 并保存文件。

    package greetings
    
    import (
        "errors"
        "fmt"
    )
    
    // Hello returns a greeting for the named person.
    func Hello(name string) (string, error) {
        // If no name was given, return an error with a message.
        if name == "" {
            return "", errors.New("empty name")
        }
    
        // If a name was received, return a value that embeds the name
        // in a greeting message.
        message := fmt.Sprintf("Hi, %v. Welcome!", name)
        return message, nil
    }
    

    在此代码中,您

    • 修改函数,使其返回两个值:一个 string 和一个 error。您的调用方将检查第二个值以确定是否发生了错误。(任何 Go 函数都可以返回多个值。有关更多信息,请参阅 Effective Go。)
    • 导入 Go 标准库 errors 包,以便您可以使用其 errors.New 函数
    • 添加一个 if 语句来检查无效请求(在应为名称的位置为空字符串),并在请求无效时返回错误。errors.New 函数返回一个 error,其中包含您的消息。
    • 在成功的返回值中添加 nil(表示没有错误)作为第二个值。这样,调用方就可以知道函数已成功执行。
  2. 在您的 hello/hello.go 文件中,现在处理 Hello 函数返回的错误以及非错误值。

    将以下代码粘贴到 hello.go 中。

    package main
    
    import (
        "fmt"
        "log"
    
        "example.com/greetings"
    )
    
    func main() {
        // Set properties of the predefined Logger, including
        // the log entry prefix and a flag to disable printing
        // the time, source file, and line number.
        log.SetPrefix("greetings: ")
        log.SetFlags(0)
    
        // Request a greeting message.
        message, err := greetings.Hello("")
        // If an error was returned, print it to the console and
        // exit the program.
        if err != nil {
            log.Fatal(err)
        }
    
        // If no error was returned, print the returned message
        // to the console.
        fmt.Println(message)
    }
    

    在此代码中,您

    • 配置 log,使其在日志消息的开头打印命令名称(“greetings: ”),而不带时间戳或源文件名信息。
    • Hello 的两个返回值(包括 error)都赋给变量。
    • Hello 的参数从 Gladys 的名字更改为空字符串,以便您可以试用错误处理代码。
    • 查找非 nilerror 值。在这种情况下,继续执行没有意义。
    • 使用标准库 log 包中的函数输出错误信息。如果您收到错误,请使用 log 包的 Fatal 函数 来打印错误并停止程序。
  3. hello 目录的命令行中,运行 hello.go 以确认代码正常工作。

    现在您传递了一个空名称,您将收到一个错误。

    $ go run .
    greetings: empty name
    exit status 1
    

这就是 Go 中常见的错误处理方式:将错误作为值返回,以便调用方可以检查它。

接下来,您将使用 Go slice 返回一个随机选择的问候语。