Why do I get "second argument to errors.As should not be *error" build error in test only?

huangapple go评论78阅读模式
英文:

Why do I get "second argument to errors.As should not be *error" build error in test only?

问题

考虑以下测试:

import (
	"errors"
	"fmt"
	"testing"
)

func TestError(t *testing.T) {
	err := &MyError{}
	var target error
	fmt.Println(errors.As(err, &target))
}

type MyError struct{}

func (err *MyError) Error() string {
	return "oops!"
}

运行此测试会返回构建错误 second argument to errors.As should not be *error

Go Playground

然而,当在 main 中运行完全相同的代码时,程序可以正常运行:

package main

import (
	"errors"
	"fmt"
)

func main() {
	err := &MyError{}
	var target error
	fmt.Println(errors.As(err, &target))
}

type MyError struct{}

func (err *MyError) Error() string {
	return "oops!"
}

Go Playground

我在 Go Playground 和本地开发环境中都看到了这种行为,两者都使用 Go 1.20。

这是 Go 的一个 bug 吗?

编辑

我可以通过创建一个 Error 类型来解决测试中的构建失败:

package main

import (
	"errors"
	"fmt"
	"testing"
)

type Error error // <===== 添加 error 类型

func TestError(t *testing.T) {
	err := &MyError{}
	var target Error // <===== 使用 Error 类型
	fmt.Println(errors.As(err, &target))
}

type MyError struct{}

func (err *MyError) Error() string {
	return "oops!"
}
英文:

Consider the following test:

import (
	&quot;errors&quot;
	&quot;fmt&quot;
	&quot;testing&quot;
)

func TestError(t *testing.T) {
	err := &amp;MyError{}
	var target error
	fmt.Println(errors.As(err, &amp;target))
}

type MyError struct{}

func (err *MyError) Error() string {
	return &quot;oops!&quot;
}

Running this test returns the build error second argument to errors.As should not be *error.

Go Playground

However, when running the exact same code in main, then the program runs without issues:

package main

import (
	&quot;errors&quot;
	&quot;fmt&quot;
)

func main() {
	err := &amp;MyError{}
	var target error
	fmt.Println(errors.As(err, &amp;target))
}

type MyError struct{}

func (err *MyError) Error() string {
	return &quot;oops!&quot;
}

Go Playground

I am seeing this behavior in the Go Playground and my local development environment, both of which are using Go 1.20.

Is this a bug in Go?

Edit

I can work around the build failure in the test by creating an Error type:

package main

import (
	&quot;errors&quot;
	&quot;fmt&quot;
	&quot;testing&quot;
)

type Error error // &lt;===== Add error type

func TestError(t *testing.T) {
	err := &amp;MyError{}
	var target Error // &lt;===== Use Error type
	fmt.Println(errors.As(err, &amp;target))
}

type MyError struct{}

func (err *MyError) Error() string {
	return &quot;oops!&quot;
}

答案1

得分: 6

错误是由go vet命令报告的。go test命令会自动运行go vet来报告重要的问题。go build命令不会运行go vet命令。

这个警告不是Go语言中的一个bug。

在调用errors.As时,将*error作为第二个参数是没有意义的,因为你已经知道第一个参数满足error接口。你几乎肯定是在做一些错误的操作。

英文:

The error is reported by the go vet command. The go test command automatically runs go vet to report significant problems. The go build command does not run the go vet command.

The warning is not a bug in Go.

There's no purpose in calling errors.As with a *error as the second argument because you already know that the first argument satisfies the error interface. You are almost certainly doing something wrong.

huangapple
  • 本文由 发表于 2023年2月18日 06:25:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/75489773.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定