英文:
panic: errors: *target must be interface or implement error in Go
问题
我正在为Go语言编写一个处理JSON反序列化错误的函数:
import "github.com/pkg/errors"
func parseJSONError(err error) {
var uterr json.UnmarshalTypeError
if errors.As(err, &uterr) {
//...
return
}
var serr json.SyntaxError
if errors.As(err, &serr) {
//...
return
}
}
但是在errors.As()
函数中出现了恐慌错误:panic: errors: *target must be interface or implement error
。
我们可以从github.com/pkg/errors文档中了解到target
的含义:
func As(err error, target interface{}) bool
问题在于json.UnmarshalTypeError
和json.SyntaxError
实际上都实现了error
接口。我们可以从encoding/json文档中了解到这一点。所以我不知道我做错了什么。即使将uterr
和serr
显式转换为interface{}
也无法解决这个问题。
这个恐慌错误在github.com/pkg/errors
和标准的errors
包中都会发生。
英文:
I am making a json unmarshalling error handling function in Go:
import "github.com/pkg/errors"
func parseJSONError(err error) {
var uterr json.UnmarshalTypeError
if errors.As(err, &uterr) {
//...
return
}
var serr json.SyntaxError
if errors.As(err, &serr) {
//...
return
}
}
But there is a panic in errors.As()
: panic: errors: *target must be interface or implement error
.
What is target we can learn from the github.com/pkg/errors documentation:
func As(err error, target interface{}) bool
The problem is that both json.UnmarshalTypeError
and json.SyntaxError
actually implement the error
interface. We can learn it from the encoding/json documentation. So I do not have any idea what I am doing wrong. Even explicit casting uterr
and serr
to the interface{}
does not save the situation.
The panic occurs in both github.com/pkg/errors
and standard errors
packages.
答案1
得分: 12
errors.As
的文档说明如下:
> 如果目标不是非空指针,要么是实现了error
接口的类型,要么是任何接口类型,As
将会引发panic。如果err
为nil,则As
返回false。
因此,你需要考虑以下几点:
json.UnmarshalTypeError
没有实现error
接口。*json.UnmarshalTypeError
实现了error
接口,因为它的方法Error() string
具有指针接收器(文档)。- 根据文档,
errors.As
需要一个指向实现了error
接口的类型的指针,所以你需要使用**json.UnmarshalTypeError
。
将代码修改为:
uterr := &json.UnmarshalTypeError{}
if errors.As(err, &uterr) {
// ...
return
}
英文:
The documentation of errors.As
states:
> As will panic if target is not a non-nil pointer to either a type that implements error, or to any interface type. As returns false if err is nil.
So you have to consider the following:
json.UnmarshalTypeError
does not implementerror
.*json.UnmarshalTypeError
does, because the methodError() string
has a pointer receiver (docs)- based on the documentation,
errors.As
wants a pointer to what implementserror
, so you need**json.UnmarshalTypeError
Change the code to:
uterr := &json.UnmarshalTypeError{}
if errors.As(err, &uterr) {
// ...
return
}
答案2
得分: 0
你也可以简单地添加-unsafeptr
标志。像这样:
go vet -unsafeptr ./...
英文:
You also can simply add -unsafeptr
flag. Like so:
go vet -unsafeptr ./...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论