Как я могу создать нулевую ошибку, используя рефлекс Голанга? - PullRequest
0 голосов
/ 29 июня 2018

Я пишу функцию с помощью refle.MakeFunc. Эта функция может вернуть ошибку. Когда это успешно, я хочу, чтобы это возвратило ноль для его возвращаемого значения ошибки. Как я могу сделать это с помощью отражения? В настоящее время у меня есть это:

package main

import (
    "fmt"
    "reflect"
    "errors"        
)

func main() {
    fmt.Println("Hello, playground")
    f := func() error {return nil}
    fn := reflect.MakeFunc(reflect.TypeOf(f), func(args []reflect.Value) []reflect.Value {
        return []reflect.Value{reflect.New(reflect.TypeOf(errors.New("")))}
    }).Interface().(func() error)
    fmt.Printf("err: %v", fn())
}

Я получаю panic: reflect: function created by MakeFunc using closure returned wrong type: have **errors.errorString for error. Я также попытался добавить .Elem() после reflect.New(reflect.TypeOf(errors.New(""))), но я получил panic: reflect: function created by MakeFunc using closure returned wrong type: have *errors.errorString for error. Я попытался .Elem().Elem(), и у меня возникла ошибка сегментации.

Как я могу получить отражение. Значение, представляющее нулевую ошибку?

Ответы [ 2 ]

0 голосов
/ 29 июня 2018

Используйте следующее:

var nilError = reflect.Zero(reflect.TypeOf((*error)(nil)).Elem())

func main() {
    fmt.Println("Hello, playground")
    f := func() error { return nil }
    fn := reflect.MakeFunc(reflect.TypeOf(f), func(args []reflect.Value) []reflect.Value {
        return []reflect.Value{nilError}
    }).Interface().(func() error)
    fmt.Printf("err: %v", fn())
}

Давайте разберемся с этим. Первый шаг - получить reflect.Type для error: reflect.TypeOf((*error)(nil)).Elem(). Более простой reflect.TypeOf((error)(nil)) не работает, потому что конкретное значение аргумента - nil. Там нет типа для nil и это не тот тип, который мы хотим в любом случае. Обходной путь должен передать указатель на error и затем вызвать Elem() на типе, чтобы получить relfect.Type для error.

Второй шаг - создать нулевое значение для типа.

0 голосов
/ 29 июня 2018

Я нашел один путь - reflect.ValueOf(f).Call(nil). Может быть, есть лучший.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...