面试题答案
一键面试1. 错误处理的基本方式
在Go语言中,函数通常会返回一个error
类型的值来表示是否发生错误。例如:
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf("division by zero")
}
return a / b, nil
}
2. 错误传递
- 简单传递:在多层函数调用中,函数可以直接返回内部调用产生的错误。
func calculate() (float64, error) {
result, err := divide(10, 0)
if err != nil {
return 0, err
}
return result, nil
}
- 包装传递:有时候需要对错误进行包装,添加更多上下文信息。Go 1.13引入了
fmt.Errorf
的%w
动词来实现错误包装。
func complexCalculation() (float64, error) {
result, err := divide(10, 0)
if err != nil {
return 0, fmt.Errorf("complex calculation failed: %w", err)
}
return result, nil
}
3. 错误分层处理
- 顶层处理:在应用程序的顶层(如
main
函数或HTTP处理函数),可以进行统一的错误处理,记录错误日志并向用户返回合适的错误信息。
func main() {
result, err := complexCalculation()
if err != nil {
log.Printf("Fatal error: %v", err)
os.Exit(1)
}
fmt.Println(result)
}
- 中间层处理:在中间层函数中,可以根据错误类型进行部分处理,然后决定是否继续向上传递错误。
func intermediateFunction() (float64, error) {
result, err := divide(10, 0)
if err != nil {
if errors.Is(err, fmt.Errorf("division by zero")) {
// 进行特定处理,如记录日志
log.Println("Division by zero occurred")
}
return 0, err
}
return result, nil
}
4. 避免错误处理代码冗余
- 使用辅助函数:将通用的错误处理逻辑封装成辅助函数。
func handleError(err error, msg string) {
if err != nil {
log.Printf("%s: %v", msg, err)
}
}
func someFunction() {
result, err := divide(10, 0)
handleError(err, "Division operation failed")
if err == nil {
fmt.Println(result)
}
}
- 错误类型断言与处理:在合适的地方,通过类型断言对不同类型的错误进行不同处理,而不是重复相同的错误处理代码。
func processError(err error) {
if divideErr, ok := err.(*DivideError); ok {
// 针对DivideError类型错误的特定处理
fmt.Printf("Divide error: %v\n", divideErr)
} else {
// 其他错误的通用处理
fmt.Printf("Other error: %v\n", err)
}
}
其中DivideError
是自定义错误类型:
type DivideError struct {
Message string
}
func (de *DivideError) Error() string {
return de.Message
}