How to get access to a custom type in a reflect.Call return? - go

I know its not idiomatic to write generic functions in Go, but I want to explore my options before I dive into the go generate.
The problem I have is that the Value.Call() returns a slice where the element I interested in is a pointer to a custom struct. Seems like I cant find a way to access this.
returns := listMethod.Call([]reflect.Value{reflect.ValueOf(filter)})
fmt.Println(returns)
output
[<vspk.EnterpriseProfilesList Value> <*bambou.Error Value>]
type definition:
type EnterpriseProfilesList []*EnterpriseProfile
I want to get access to the vspk.EnterpriseProfilesList, but I am struggling to make it.
If I try to retrieve the underlying value like this:
returns := listMethod.Call([]reflect.Value{reflect.ValueOf(filter)})
ret1 := returns[0].Interface()
fmt.Println(ret1)
I receive
[0xc0000fc7e0]

Value.Call() returns a value of type []reflect.Value. What you're interested in is the first value of that slice: returns[0].
This will be of course of type reflect.Value. To extract the value wrapped in it, use Value.Interface().
This will be of type interface{}. If you need the concrete type, use a type assertion:
returns[0].Interface().(spk.EnterpriseProfilesList)
For example:
if list, ok := returns[0].Interface().(spk.EnterpriseProfilesList); ok {
// here list is of type spk.EnterpriseProfilesList
} else {
// it was nil or not of type spk.EnterpriseProfilesList
}

Related

Get inteface's dynamic value when there is a pointer to integer as dinamic type

I'm struggling trying to figure out how to "extract" an integer value from a interface that holds a value whose dynamic type is pointer to integer.
You may follow this ready-to-run example in order to fully get the picture of what is problem and my intention.
TD;DR:
For some reason the reflection on a first call to reflect.ValueOf(value) over an interface whose dynamic type is pointer to integer, it returns a value whose Kind() results in reflect.Ptr, when i extract again the "inner" value using reflect.ValueOf(value).Elem() i get another value whose Kind() results in reflect.Struct. I don't even code any struct, but they appears by their own "magically". So golang may not panic but i don't understand what is happening, probably i lack of some information. I would be very thankful with anyone that explaint me what is going on.
This may work for this case, but it doesn't enlight me. I would expect to have an integer value "behind" the pointer. I don't need to access for modification, i only need to get it.
It's struct because when you call ToCompliantValue inside the function, you're not passing it the value itself, you're passing a reflect.Value value, and reflect.Value is a struct. You have to handle it directly instead of trying to use recursion:
v := reflect.ValueOf(value)
fmt.Printf("Value is %+v\n", v)
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
switch v.Kind() {
// ...
Working example: https://play.golang.org/p/ndRjXJfj5xV

How to get a new variable of the same type of another variable with Golang

How can I do this? I want a function to return a variable with the same type as one of its arguments. I need something like the below:
type Whatever struct {
Title string
}
hey:= Whatever{Title:"YAY"}
thetype := reflect.ValueOf(hey).Kind()
// This does not work
BB:= new(thetype)
If you want to create a new value from a reflect.Type you can do it with reflect.New:
thetype := reflect.TypeOf(hey)
BB:= reflect.New(thetype)
This returns a reflect.Value
You can then for example use .Interface() and type assertions to get back to the original type.
Example on Go playground: https://play.golang.org/p/rL-Hm0IUpd

golang: reflect.ValueOf(x).Type() always equals to reflect.TypeOf(x)? [duplicate]

I'm not very clear about what this code snippet behaves.
func show(i interface{}) {
switch t := i.(type) {
case *Person:
t := reflect.TypeOf(i) //what t contains?
v := reflect.ValueOf(i) //what v contains?
tag := t.Elem().Field(0).Tag
name := v.Elem().Field(0).String()
}
}
What is the difference between the type and value in reflection?
reflect.TypeOf() returns a reflect.Type and reflect.ValueOf() returns a reflect.Value. A reflect.Type allows you to query information that is tied to all variables with the same type while reflect.Value allows you to query information and preform operations on data of an arbitrary type.
Also reflect.ValueOf(i).Type() is equivalent to reflect.TypeOf(i).
In the example above, you are using the reflect.Type to get the "tag" of the first field in the Person struct. You start out with the Type for *Person. To get the type information of Person, you used t.Elem(). Then you pulled the tag information about the first field using .Field(0).Tag. The actual value you passed, i, does not matter because the Tag of the first field is part of the type.
You used reflect.Value to get a string representation of the first field of the value i. First you used v.Elem() to get a Value for the struct pointed to by i, then accessed the first Field's data (.Field(0)), and finally turned that data into a string (.String()).

unmarshalling generic json with a type lookup map

I'm following up on Golang Decoding Generic JSON Objects to One of Many Formats as a way to unmarshal generic json. I'm going to have a multitude of different types tho which can be added by others, so hardcoding case statements is not feasible.
I also don't want to hardcode the type as a string, but let the ones using the library chose the "lookup" name, in case they want to rename their underlying structs later.
I am basically looking for something like this:
type myInterface interface {
Something() // irrelevant, just to show you It's not about interface{}
}
type myBar struct {} // fulfils myInterface
type mySomething struct {} // fulfils myInterface
var types = make(map[string]type) // <--- Obvious Pseudo code ;)
types["foo:bar"] = myBar // done by whoever uses the library
types["1230988"] = mySomething // ...
type storageWrapper struct {
Type string
Data json.RawMessage
}
func loadSomething(id string) myInterface {
buf := db.load(id) // pseudo code but you get the idea
sw := &storageWrapper{}
json.Unmarshal(buf, sw)
// now the interesting part
targetType := types[sw.Type]
thing := &targetType{}
json.Unmarshal(sw.Data, thing)
return thing
}
I have this feeling that I'm overthinking the whole Problem. Or that I'm trying to bend Go into something that conflicts with its underlying philosophy. I'm very open and thankful for any advice that suggests a different approach to the whole Problem
Have types be a map[string]myInterface, and to register a type, have callers store an empty value of that type (not a reference) into the map. Then, to unmarshal, you can "get the type" by copying the empty value out of the map, unmarshaling into it, and returning it (or a reference to it). The interface value will do the job of identifying which type is wanted. Plus, if users want to default some fields to non-zero/empty values in case they're not provided in the JSON, they can actually do that by storing those values within the struct in the type map.

How to convert value type by another value's reflect.Type in Golang

How to convert value type by another value's reflect.Type in Golang
maybe like this:
func Scan(value interface{}, b string) error {
converted := value.(reflect.TypeOf(b)) // do as "value.(string)"
return nil
}
How can do this properly in golang?
The only way to get a typed value out of an interface is to use a type assertion, and the syntax is value.(T) where T is a type. There's a good reason for this, because it makes the type of the type assertion expression computable: value.(T) has type T. If instead, you allowed value.(E) where E is some expression that evaluates to a reflect.Type (which I think is the gist of your question), then the compiler has no way to (in general) statically determine the type of value.(E) since it depends on the result of an arbitrary computation.

Resources