还没写好 ×
2024年6月23日
Go 语言 error 标准库
0 words
/
0 read
/
0 views

你知道go语言里面的error.as方法吗

在Go语言中,errors.As 是一个用于将错误类型转换为指定类型的工具函数。它是在Go 1.13中引入的,属于errors包的一部分。errors.As 方法的主要作用是检查错误链中的错误,看看是否有可以转换为指定类型的错误。如果有,它会将该错误赋值给目标并返回true;否则返回false。

以下是errors.As的基本使用方法:

package main

import (
    "errors"
    "fmt"
)

// 自定义错误类型
type MyError struct {
    Msg string
}

func (e *MyError) Error() string {
    return e.Msg
}

func main() {
    // 创建一个MyError类型的错误
    err := &MyError{Msg: "this is my custom error"}

    // 将错误封装在一个普通的错误类型中
    wrappedErr := fmt.Errorf("wrapped error: %w", err)

    // 目标变量,存放转换后的错误
    var myErr *MyError

    // 使用errors.As进行类型转换
    if errors.As(wrappedErr, &myErr) {
        fmt.Println("Error is of type MyError:", myErr)
    } else {
        fmt.Println("Error is not of type MyError")
    }
}

在这个示例中,errors.As 用于检查封装错误 wrappedErr 是否包含一个 MyError 类型的错误,并将其赋值给变量 myErr。如果转换成功,程序会输出 Error is of type MyError: ...,否则会输出 Error is not of type MyError

使用errors.As 可以方便地处理多层封装的错误,并对特定类型的错误做出相应的处理。

这一句为什么要加 err := &MyError{Msg: "this is my custom error"} &符号

在Go语言中,&符号用于取变量的地址,即创建指向该变量的指针。在这个例子中:

err := &MyError{Msg: "this is my custom error"}

使用&符号是为了创建一个指向MyError实例的指针。errors.As函数需要目标变量是指向错误类型的指针,因为它会将错误链中的某个错误赋值给这个指针,以便后续可以访问和处理这个错误的具体信息。

这是一个示例来解释为什么需要使用指针:

  1. 指针允许动态类型转换: 在Go语言中,接口类型(如error接口)可以保存实现该接口的任何类型的值,但接口变量本身并不知道具体的底层类型。使用指针允许errors.As函数在运行时动态地确定错误链中的错误类型,并将其赋值给指定的目标变量。

  2. 接口和值接收者的区别: 如果不使用指针,直接创建MyError实例(即值类型),当传递给errors.As时,类型断言不会成功,因为它们的底层类型不同。

下面是一个修改后的示例来说明这一点:

package main

import (
    "errors"
    "fmt"
)

// 自定义错误类型
type MyError struct {
    Msg string
}

func (e *MyError) Error() string {
    return e.Msg
}

func main() {
    // 直接创建MyError类型的实例(值类型)
    err := MyError{Msg: "this is my custom error"}

    // 将错误封装在一个普通的错误类型中
    wrappedErr := fmt.Errorf("wrapped error: %w", &err) // 注意这里使用了&符号

    // 目标变量,存放转换后的错误
    var myErr *MyError

    // 使用errors.As进行类型转换
    if errors.As(wrappedErr, &myErr) {
        fmt.Println("Error is of type MyError:", myErr)
    } else {
        fmt.Println("Error is not of type MyError")
    }
}

在上面的示例中,err := MyError{Msg: "this is my custom error"} 直接创建了一个MyError的实例(值类型),而在封装时仍然使用&err以确保传递的是指向该实例的指针。因此,errors.As函数可以正确地识别和处理该错误类型。

Continue Reading
All Articles
© 2024 Mooncyan