在`reflect.MakeFunc`中返回错误值

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

Returning error value in reflect.MakeFunc

问题

我正在尝试在 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 为 null,在这一行代码中会出现地址指针错误,这是在 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 的情况下,但问题并没有解决。

如果我创建一个虚拟的错误结构体来实现 error 接口并返回它,忽略错误返回值时必须为 nil,那么它会抱怨 由 makeFunc 创建的函数的返回值不正确

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

英文:

I am trying to create an return a function in golang which has a return type of (SomeStruct, error) (standard error interface)

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)

If err returned by .One function is null, I get address pointer error on this line, internally in golang :

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

I have tried to change the line of secondValue assignment to :

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

in the case where err == nil, however the problem did not go away.

If I create a dummy error struct that implements the interface error and return that, ignoring error return value has to be nil when it is really nil, then it complains that the return value by the function made by makeFunc is incorrect

Can you think of a way to solve this problem? (Except wrapping the error in a struct, and changing the return type to that struct instead )

答案1

得分: 2

使用以下代码行设置secondValue

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

调用ValueOf(&err)会返回一个类型为*errorreflect.Value。在该值上调用Elem()会返回一个类型为errorreflect.Value

调用ValueOf(err)会返回具体值的类型为errreflect.Value,如果err中没有具体值(err == nil),则返回一个无效的reflect.Value。无论如何,返回的reflect.Value都不具有类型error

英文:

Use this line to set secondValue:

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

The call ValueOf(&err) returns a reflect.Value with type *error. Calling Elem() on that value returns a reflect.Value with type error.

The call ValueOf(err) returns a reflect.Value with the type of the concrete value of err or an invalid reflect.Value if there is no concrete value in err (err == nil). Either way, the returned reflect.Value does not have type error.

huangapple
  • 本文由 发表于 2016年12月24日 09:17:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/41309499.html
匿名

发表评论

匿名网友

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

确定