背景
在测试error.is
时,发现一个奇怪的现象,同时使用fmt.Printf
和println
,输出顺序无法保证,也就是可能存在异步输出。
err := errors.New("standard error")
myError := MyError{1, "my error"}
if errors.Is(err, myError) {
println("println-1: myError is err----")
} else {
println("println-1: myError is not err----")
}
err = fmt.Errorf("wrapped error %w", myError)
fmt.Printf("fmt.Printf-1: err:%vn", err)
fmt.Printf("fmt.Printf-1: err:%vn", err)
println("println-2: " err.Error())
- 输出情况一:
- 输出情况二:
主要有以下几个疑问:
- 输出顺序无法保证,存在异步?
println
输出内容是红色的,stderr?- 这两个输出到控制台有啥区别,各自什么情况下使用?
经过查阅资料、调试、阅读源码发现以下几个关键信息:
println
在golang sdk中没有找到源码,属于builtin
包,是编译器内置函数,无法进入调试。而fmt.Printf
属于标准库。println
输出到stderr,fmt.Printf
输出到stdoutprintln
一般作为调试使用,生产项目里使用fmt.Printf
println
和fmt.Printf
相比,缺少很多功能:不能输出到其他io.Writer
,例如os.Stdout
、os.Stderr
、通过网络远程输出。并且不能自定义实现。- 不确定println是否为异步,但通过源码发现执行println时存在加锁操作。
- 这两个不要同时使用,无法保证顺序。
参考
- 第3章 管道符、重定向与环境变量
- Difference between fmt.Println() and println() in Go
Post Views: 6