面试题答案
一键面试1. 使用错误类型断言区分不同类型错误并针对性处理
在 Go 语言中,可以通过 errors.As
函数或类型断言来区分不同类型的错误。假设我们有如下代码:
package main
import (
"errors"
"fmt"
"io"
)
// 自定义错误类型
type MyUnexpectedEOFError struct {
// 可以添加额外的字段
}
func (m *MyUnexpectedEOFError) Error() string {
return "my unexpected end of file error"
}
func readData(reader io.Reader) error {
// 模拟读取数据
// 这里假设会返回不同类型的错误
return &MyUnexpectedEOFError{}
}
func main() {
var err error
err = readData(nil)
if err != nil {
varUnexpectedEOF := &MyUnexpectedEOFError{}
if errors.As(err, &varUnexpectedEOF) {
fmt.Println("处理自定义UnexpectedEOF错误:", varUnexpectedEOF.Error())
} else if errors.Is(err, io.EOF) {
fmt.Println("处理EOF错误")
} else {
fmt.Println("处理其他错误:", err.Error())
}
}
}
在上述代码中,readData
函数模拟从 io.Reader
读取数据并可能返回不同类型的错误。在 main
函数中,通过 errors.As
来尝试将错误断言为 MyUnexpectedEOFError
类型,如果断言成功则进行针对性处理;同时也使用 errors.Is
来判断是否为 io.EOF
错误。如果都不匹配,则按其他错误处理。
2. 通过抽象错误类型提高代码可维护性和扩展性
通过设计一个自定义的错误接口,可以让不同的错误类型实现该接口,从而在处理错误时能够更统一和灵活。
package main
import (
"fmt"
)
// 自定义错误接口
type MyErrorInterface interface {
Error() string
// 可以添加其他方法,例如获取错误详细信息等
GetDetails() string
}
// 自定义错误类型1
type MyErrorType1 struct {
details string
}
func (m *MyErrorType1) Error() string {
return "MyErrorType1: " + m.details
}
func (m *MyErrorType1) GetDetails() string {
return m.details
}
// 自定义错误类型2
type MyErrorType2 struct {
details string
}
func (m *MyErrorType2) Error() string {
return "MyErrorType2: " + m.details
}
func (m *MyErrorType2) GetDetails() string {
return m.details
}
func doSomething() error {
// 这里假设根据不同情况返回不同的自定义错误
return &MyErrorType1{details: "具体错误详情1"}
}
func main() {
var err error
err = doSomething()
if err != nil {
if myErr, ok := err.(MyErrorInterface); ok {
fmt.Println("自定义错误处理:", myErr.Error())
fmt.Println("错误详情:", myErr.GetDetails())
} else {
fmt.Println("其他错误:", err.Error())
}
}
}
在上述代码中,定义了 MyErrorInterface
接口,然后 MyErrorType1
和 MyErrorType2
实现了该接口。在 doSomething
函数中可能返回不同类型的实现了该接口的错误。在 main
函数中,通过类型断言判断错误是否实现了 MyErrorInterface
接口,如果实现了则进行统一的处理,提高了代码的可维护性和扩展性。如果是其他不实现该接口的错误,则按普通错误处理。