【问题标题】:Returning error value in reflect.MakeFunc在 reflect.MakeFunc 返回错误值
【发布时间】:2017-05-09 15:14:13
【问题描述】:

我正在尝试在 golang 中创建一个返回函数,该函数的返回类型为 (SomeStruct, error)(标准错误接口)

fn := func (args []reflect.Value) []reflect.Value {
    database := mongoConnectorInstance.GetDatabase()
    defer database.Session.Close()

    selector := bson.M{
        field : args[0].Interface(),
    }

    newValue := reflect.New(fieldFunctionValue.Type().Out(0))
    newValueInterface := newValue.Interface()
    fmt.Println(reflect.TypeOf(newValueInterface))

    err := database.C(collection).Find(selector).One(newValueInterface)

    secondValue := reflect.ValueOf(err)
    return []reflect.Value {
        newValue.Elem(),
        secondValue,
    }
}

resultFunctionValue := reflect.MakeFunc(fieldFunctionValue.Type(), fn)

如果 .One 函数返回的 err 为空,我在这一行上得到地址指针错误,在 golang 内部:

panic("reflect: function created by MakeFunc using " + funcName(f) +
                    " returned wrong type: have " +
                    out[i].typ.String() + " for " + typ.String())

我已尝试将 secondValue 赋值行更改为:

secondValue := reflect.ValueOf((error)(nil)) 

在err == nil的情况下,问题并没有消失。

如果我创建一个实现接口错误的虚拟错误结构并返回它,忽略错误返回值必须为 nil,而实际上它是 nil,然后它会抱怨 the return value by the function made by makeFunc is incorrect

你能想出解决这个问题的方法吗? (除了将错误包装在结构中,并将返回类型更改为该结构)

【问题讨论】:

    标签: go reflection


    【解决方案1】:

    使用此行设置secondValue:

    secondValue := reflect.ValueOf(&err).Elem()
    

    调用ValueOf(&err) 返回一个reflect.Value 类型为*error。对该值调用Elem() 会返回一个reflect.Value,其类型为error。

    调用ValueOf(err) 返回一个reflect.Value,其具体值为err,如果err (err == nil) 中没有具体值,则返回一个无效的reflect.Value。无论哪种方式,返回的reflect.Value 都没有error 类型。

    【讨论】:

    • 我为没有想到这个而感到羞耻。非常感谢
    猜你喜欢
    • 2019-02-03
    • 2015-06-19
    • 2014-01-16
    • 2019-10-13
    • 2020-10-05
    • 2015-11-19
    • 2020-05-27
    • 2017-04-16
    • 2017-08-26
    相关资源
    最近更新 更多