Почему я получаю «второй аргумент для ошибок. Как не должно быть * error» ошибка сборки только в тесте?

Рассмотрим следующий тест:

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?

Редактировать

Я могу обойти ошибку сборки в тесте, создав тип Error:

package main

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

type Error error // <===== Add error type

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

type MyError struct{}

func (err *MyError) Error() string {
    return "oops!"
}
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
1
0
69
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Об ошибке сообщает команда go vet. Команда go test автоматически запускает go vet, чтобы сообщить о серьезных проблемах. Команда go build не запускает команду go vet.

Предупреждение не является ошибкой в ​​Go.

Нет смысла вызывать errors.As с *error в качестве второго аргумента, потому что вы уже знаете, что первый аргумент удовлетворяет интерфейсу error. Вы почти наверняка делаете что-то не так.

Ах, я упустил из виду, что go test работает go vet, так что это должно быть ответом, почему я вижу это только с go test. Сказав это, причина, по которой я столкнулся с этим, заключается в том, что я искал, как использовать errors.As в табличных тестах. Типичный пример того, что я пытаюсь сделать, есть в стандартной библиотеке. Обратите внимание, что они напечатали tc.target как any, и мне казалось, что не должно быть причин, по которым tc.target нельзя набирать как error и назначать разные типы ошибок в каждом тестовом примере.

Sam Herrmann 18.02.2023 00:04

В вашем тесте используется error в качестве типа целевого значения. Таблица в стандартной библиотеке test хранит указатель на значение типа ошибки. Стандартная библиотека использует any вместо error, потому что указатель на ошибку не удовлетворяет интерфейсу error. Следуйте шаблону в тесте стандартной библиотеки. В частности, сохраните указатель на целевое значение в таблице и передайте это значение непосредственно в errors.As (не берите адрес значения в таблице).

pEnnystEvEns 18.02.2023 03:30

Другие вопросы по теме