面试题答案
一键面试区别
errors.New
:- 功能较为简单,直接创建一个带有固定错误信息的错误对象。例如:
err := errors.New("文件不存在")
,错误信息就是传入的字符串,不能动态格式化。
- 功能较为简单,直接创建一个带有固定错误信息的错误对象。例如:
fmt.Errorf
:- 功能更强大,支持格式化字符串,类似于
fmt.Sprintf
。例如:filename := "test.txt"; err := fmt.Errorf("文件 %s 不存在", filename)
,可以根据不同的变量动态生成错误信息。
- 功能更强大,支持格式化字符串,类似于
适用场景
- 优先选择
errors.New
的场景:- 当错误信息是固定不变,不需要根据不同情况动态生成时,使用
errors.New
。这样代码更为简洁,性能上也稍有优势,因为不需要处理格式化操作。例如,在一些基础的、通用的错误场景,如“连接数据库失败”这样固定的错误提示。
- 当错误信息是固定不变,不需要根据不同情况动态生成时,使用
- 优先选择
fmt.Errorf
的场景:- 当错误信息需要根据不同的变量值或情况动态生成时,应优先使用
fmt.Errorf
。例如在处理文件操作时,文件名可能不同,错误信息需要包含具体文件名,此时fmt.Errorf
就很合适。
- 当错误信息需要根据不同的变量值或情况动态生成时,应优先使用
fmt.Errorf
实现原理
fmt.Errorf
内部实际上调用了fmt.Sprintf
来进行格式化字符串操作。它先按照格式化规则将传入的格式化字符串和参数进行处理,生成一个完整的字符串,然后再使用这个生成的字符串创建一个新的错误对象。例如:
package main
import (
"fmt"
)
func main() {
var name = "John"
err := fmt.Errorf("用户 %s 不存在", name)
// 这里先调用fmt.Sprintf生成"用户 John 不存在"字符串
// 然后用这个字符串创建错误对象
fmt.Println(err.Error())
}
这样就实现了动态生成错误信息的功能。