Goのfmt.Errorfでは%wを使ったほうがいいらしい

Goのfmt.Errorfでは、%vより%wを使ったほうがいいらしいです。

fmt.Errorf を使って error をラップするとき、なんとなく便利な %v を使って

1
2
3
if err != nil {
    return fmt.Errorf("unable to hoge: %v", err)
}

って書きがちだったんですが、公式ドキュメントによると

If the format specifier includes a %w verb with an error operand, the returned error will implement an Unwrap method returning the operand. It is invalid to include more than one %w verb or to supply it with an operand that does not implement the error interface. The %w verb is otherwise a synonym for %v.

とあり、%w で一個だけエラーを指定してあげると、Go1.13からの Unwrap() error を実装した error を返してくれるらしいです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package main

import (
 "errors"
 "fmt"
)

func main() {
 e := errors.New("fuga")
    err := fmt.Errorf("unable to %s: %w", "hoge", e)
 fmt.Println(errors.Unwrap(err))
}

playground

でも

1
fuga

とプリントされるのでちゃんとできてますね。かしこい!