我有一个错误对象,在控制台上打印时会给我Token is expired
如何将其与特定错误值进行比较。我尝试了这个但是没有用。
if(err == errors.New("Token is expired")){
log.Printf("Unauthorised: %s\n", err)
}
答案 0 :(得分:25)
尝试
double no=12.786;
DecimalFormat dec = new DecimalFormat("#0.00");
System.out.println(dec.format(no));
或者通过实现错误界面来创建自己的错误。
答案 1 :(得分:24)
在库中定义错误值
package fruits
var NoMorePumpkins = errors.New("No more pumpkins")
不要在代码中的任何位置创建errors.New
错误,但每当发生错误时都会返回预定义值,然后您可以执行以下操作:
package shop
if err == fruits.NoMorePumpkins {
...
}
请参阅io
包错误以供参考。
答案 2 :(得分:12)
导出错误变量的包是惯用的,因此其他人可以与它们进行比较。
E.g。如果错误来自名为 myPkg 的包,并且定义为:
var ErrTokenExpired error = errors.New("Token is expired")
您可以将错误直接比较为:
if err == myPkg.ErrTokenExpired {
log.Printf("Unauthorised: %s\n", err)
}
如果错误来自第三方软件包并且不使用导出的错误变量,那么您可以做的只是与从err.Error()获得的字符串进行比较,但要小心这种方法错误字符串可能不会在主要版本中发布,并且会破坏您的业务逻辑。
答案 3 :(得分:7)
错误类型是接口类型。错误变量表示可以将自身描述为字符串的任何值。这是界面的声明:
type error interface {
Error() string
}
最常用的错误实现是错误包的未导出错误字符串类型:
// errorString is a trivial implementation of error.
type errorString struct {
s string
}
func (e *errorString) Error() string {
return e.s
}
请参阅此工作代码输出(The Go Playground):
package main
import (
"errors"
"fmt"
"io"
)
func main() {
err1 := fmt.Errorf("Error")
err2 := errors.New("Error")
err3 := io.EOF
fmt.Println(err1) //Error
fmt.Printf("%#v\n", err1) // &errors.errorString{s:"Error"}
fmt.Printf("%#v\n", err2) // &errors.errorString{s:"Error"}
fmt.Printf("%#v\n", err3) // &errors.errorString{s:"EOF"}
}
输出:
Error
&errors.errorString{s:"Error"}
&errors.errorString{s:"Error"}
&errors.errorString{s:"EOF"}
比较运算符比较两个操作数并产生一个无类型的布尔值 值。在任何比较中,第一个操作数必须可分配给 第二个操作数的类型,反之亦然。
等于运算符
==
和!=
适用于操作数 可比性。指针值具有可比性。如果它们两个指针值相等 指向相同的变量或者两者的值都为零。指针 不同的零大小变量可能相等也可能不相等。
界面值具有可比性。如果两个接口值相等 它们具有相同的动态类型和相同的动态值,或者两者都有 没有价值。
非接口类型X的值x和接口类型T的值t 当X类型的值具有可比性且X实现时,可比较 如果t的动态类型与X和t相同,它们是相等的 动态值等于x。
如果所有字段都具有可比性,则结构值具有可比性。二 如果相应的非空白字段是,则struct值相等 相等。
所以:
1-您可以使用Error()
,例如此工作代码(The Go Playground):
package main
import (
"errors"
"fmt"
)
func main() {
err1 := errors.New("Token is expired")
err2 := errors.New("Token is expired")
if err1.Error() == err2.Error() {
fmt.Println(err1.Error() == err2.Error()) // true
}
}
输出:
true
2-此外,您可以将其与nil
进行比较,例如此工作代码(The Go Playground):
package main
import (
"errors"
"fmt"
)
func main() {
err1 := errors.New("Token is expired")
err2 := errors.New("Token is expired")
if err1 != nil {
fmt.Println(err1 == err2) // false
}
}
输出:
false
3-此外,您可以将其与完全相同的错误进行比较,例如此工作代码
(The Go Playground):
package main
import (
"fmt"
"io"
)
func main() {
err1 := io.EOF
if err1 == io.EOF {
fmt.Println("err1 is : ", err1)
}
}
输出:
err1 is : EOF
答案 4 :(得分:6)
声明错误并将其与'==
'(如err == myPkg.ErrTokenExpired
比较)已不再是Go 1.13(2019年第三季度)的最佳做法
Go 1.13包含对错误包装的支持,该支持首先在Error Values proposal中提出,并在associated issue上进行了讨论。
错误
e
可以通过提供返回w
的{{1}}方法来包装另一个错误Unwrap
。
w
和e
都可供程序使用,从而允许w
为e
提供附加上下文或重新解释它,同时仍允许程序根据{{1}做出决定}。为了支持包装,
fmt.Errorf
现在有一个w
动词来创建包装错误,并在errors
包中提供了三个新功能(errors.Unwrap
,errors.Is
和errors.As
)简化了包装和检查包装的错误。
因此Error Value FAQ解释:
您需要做好准备,以防您收到的错误得到解决。
如果您当前使用
w
比较错误,请改用%w
。
示例:==
成为
errors.Is
- 检查是否需要更改
if err == io.ErrUnexpectedEOF
的形式。- 与
if errors.Is(err, io.ErrUnexpectedEOF)
的比较无需更改,因为err != nil
绝对不能包装。如果使用类型断言或类型开关检查错误类型,请改用
io.EOF
。示例:io.EOF
成为
errors.As
还使用此模式检查错误是否实现了接口。 (这是在少数情况下适合使用指向接口的指针的情况之一。)
将类型开关重写为
if e, ok := err.(*os.PathError); ok
的序列。
答案 5 :(得分:6)
不鼓励按字符串比较错误。相反,您应该按值比较错误。
package main
import "errors"
var NotFound = errors.New("not found")
func main() {
if err := doSomething(); errors.Is(err, NotFound) {
println(err)
}
}
func doSomething() error {
return NotFound
}
如果您是库作者并且想导出错误,以便用户可以对不同类型的错误采取不同的行动,则它特别有用。标准库也可以。
此方法的问题在于,由于Go不支持不变值,因此任何人都可以更改导出的值。但是,没有什么可以阻止您将字符串用作错误并将其设置为const
。
package main
type CustomError string
func (ce CustomError) Error() string {
return string(ce)
}
const NotFound CustomError = "not found"
func main() {
if err := doSomething(); errors.Is(err, NotFound) {
println(err)
}
}
func doSomething() error {
return NotFound
}
这是更冗长但更安全的方法。
答案 6 :(得分:0)
您应该首先考虑按值比较错误,如其他解决方案中所述:
if errors.Is(err1, err2) {
// do sth
}
但是在某些情况下,函数返回的错误有点复杂,例如一个错误被多次包装,在每个函数调用中添加一个上下文,如 fmt.Errorf("some context: %w", err)
,您可能只想比较两个错误的错误消息。在这种情况下,您可以这样做:
// SameErrorMessage checks whether two errors have the same messages.
func SameErrorMessage(err, target error) bool {
if target == nil || err == nil {
return err == target
}
return err.Error() == target.Error()
}
func main() {
...
if SameErrorMessage(err1, err2) {
// do sth
}
}
请注意,如果您只是使用
if err1.Error() == err2.Error() {
// do sth
}
如果 err1
或 err2
为 nil
,您可能会面临 nil 指针取消引用运行时错误。