• 简体中文
  • 返回并处理错误

    注意: 本文是系列教程的一部分,该系列始于 创建 Go 模块

    处理错误是可靠代码的重要组成部分。在本节中,你将添加一些代码以从 greetings 模块返回错误,然后在调用者中处理它。

    步骤

    1. 修改 greetings/greetings.go 以返回错误

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

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

    package greetings
    
    import (
        "errors"
        "fmt"
    )
    
    // Hello 返回指定人的问候语。
    func Hello(name string) (string, error) {
        // 如果没有提供名字,则返回带有消息的错误。
        if name == "" {
            return "", errors.New("empty name")
        }
    
        // 如果收到名字,则返回嵌入名字在问候语中的值。
        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 文件中,处理现在由 Hello 函数返回的错误以及非错误值。

    将以下代码粘贴到 hello.go

    package main
    
    import (
        "fmt"
        "log"
    
        "example.com/greetings"
    )
    
    func main() {
        // 设置预定义 Logger 的属性,包括日志条目前缀和一个禁用打印时间、源文件和行号的标志。
        log.SetPrefix("greetings: ")
        log.SetFlags(0)
    
        // 请求问候语。
        message, err := greetings.Hello("")
        // 如果返回了错误,则将其打印到控制台并退出程序。
        if err != nil {
            log.Fatal(err)
        }
    
        // 如果没有返回错误,则将返回的消息打印到控制台。
        fmt.Println(message)
    }

    在这段代码中,你:

    • 配置 log 在其日志消息的开头打印命令名称("greetings: "),不带时间戳或源文件信息。
    • 分配 Hello 的所有返回值,包括 error,到变量。
    • Hello 的参数从 Gladys 的名字更改为空字符串,以便你可以尝试错误处理代码。
    • 查找非 nil 的 error 值。在这种情况下,继续执行没有意义。
    • 使用标准库的 log 包中的函数来输出错误信息。如果你收到错误,则使用 log 包的 Fatal 函数 打印错误并停止程序。

    3. 运行 hello.go 以确认代码正常工作

    hello 目录的命令行中,运行 hello.go 以确认代码正常工作。

    现在你传递了一个空名字,你将得到一个错误。

    $ go run .
    greetings: empty name
    exit status 1

    结论

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

    接下来,你将使用 Go 切片返回随机选择的问候语。