我有以下代码(也位于https://play.golang.org/p/9MlhhUPZRog):
package main
import (
"errors"
"fmt"
"os"
)
func main() {
var pathError *os.PathError
// Generate the error
_, err := os.Open("I_DO_NOT_EXIST.TXT");
// Print, everything is OK here
fmt.Println(err);
// Wrap the error multiple times
err = fmt.Errorf("%w; another error", err)
err = fmt.Errorf("%w; another error", err)
// Is it path error?
fmt.Println(err, " ---- is path error? ----> ", errors.Is(err, pathError))
// !!! UNCOMMENT THE LINE BELOW TO SEE THE DIFFERENCE !!!
// if errors.As(err, &pathError) {}
// Is it path error now?
fmt.Println(err, " ---- is path error? ----> ", errors.Is(err, pathError))
}
结果是:
open I_DO_NOT_EXIST.TXT: no such file or directory
open I_DO_NOT_EXIST.TXT: no such file or directory; another error; another error ---- is path error? ----> false
open I_DO_NOT_EXIST.TXT: no such file or directory; another error; another error ---- is path error? ----> false
这是有道理的。但是,如果我取消注释
if errors.As...
行,结果将完全不同:open I_DO_NOT_EXIST.TXT: no such file or directory
open I_DO_NOT_EXIST.TXT: no such file or directory; another error; another error ---- is path error? ----> false
open I_DO_NOT_EXIST.TXT: no such file or directory; another error; another error ---- is path error? ----> true
最后一次检查时显示
true
。为什么
errors.As
突变了err
变量? 最佳答案
根据文档:
当顺序解包其第一个参数时,寻找可以分配给其第二个参数的错误,该错误必须是一个指针。如果成功,它将执行分配并返回true。否则,它返回false。
因此,当您执行errors.As(err, &pathError)
时,pathError将设置为err。
您可以通过以下代码进行验证:
package main
import (
"errors"
"fmt"
"os"
)
func main() {
var pathError *os.PathError
// Generate the error
_, err := os.Open("I_DO_NOT_EXIST.TXT");
// Print, everything is OK here
fmt.Println(err);
//pathError is nil here
fmt.Println(pathError)
// Is it path error?
fmt.Println(err, " ---- is path error? ----> ", errors.Is(err, pathError))
fmt.Println()
//pathError is set to err here
if errors.As(err, &pathError) {}
fmt.Println(err);
//pathError as err here
fmt.Println(pathError)
// Is it path error?
fmt.Println(err, " ---- is path error? ----> ", errors.Is(err, pathError))
}