Reflect.Value.FieldByName causing Panic - reflection

I'm getting the following error when calling the .FieldByName method of a reflected value, the exact error is :-
panic: reflect: call of reflect.Value.FieldByName on ptr Value
and the code is :-
s := reflect.ValueOf(&value).Elem() (value is a struct)
metric := s.FieldByName(subval.Metric).Interface() (subval.Metric is a string)
I understand this isn't much, but this is all the information I can get.
Here's a link to the code on Go Playground: http://play.golang.org/p/E038cPOoGp

Your value is already a pointer to a struct. Try printing out s.Kind() in your code.
There's no reason to take the address of value, then call Elem() on that reflect.Value, which dereferences the pointer you just created.
s := reflect.ValueOf(value).Elem()
metric := s.FieldByName(subvalMetric).Interface()
fmt.Println(metric)

If you add few println you understand what happens:
http://play.golang.org/p/-kaz105_En
for _, Value:= range NewMap {
s := reflect.ValueOf(&Value).Elem()
println(s.String())
println(s.Elem().String())
metric := s.Elem().FieldByName(subvalMetric).Interface()
fmt.Println(metric)
}
Output:
<*main.Struct1 Value>
<main.Struct1 Value>
abc

Related

reflect.Pointer() returned value is not the value address

type BookInfo struct {
Meta *TableMeta
...
}
func (si *schemaInfo) getTabInfo(obj interface{}) (*tabInfo, error) {
typ := reflect.TypeOf(obj)
val := reflect.ValueOf(obj)
if typ.Kind() != reflect.Ptr {
return nil, errors.New("nborm.schemaInfo.getDBInfo() error: required a pointer")
}
meta := *(**TableMeta)(unsafe.Pointer(val.Pointer()))
...
}
getTabInfo() works well, but I want to know why val.Pointer() return a value of **TableMeta? Why not a *TableMeta?The document of reflect says,
Pointer returns v's value as a uintptr. It returns uintptr instead of
unsafe.Pointer so that code using reflect cannot obtain
unsafe.Pointers without importing the unsafe package explicitly. It
panics if v's Kind is not Chan, Func, Map, Ptr, Slice, or
UnsafePointer.
In my mind:
info := &BookInfo{}
val := reflect.ValueOf(info)
ptr := val.Pointer()
meta := (*TableMeta)(unsafe.Pointer(val.Pointer()))
should work, but infact when I called val.Pointer(), the returned value is the pointer of *TableMeta(**TableMeta).
The value you have is a pointer to a BookInfo struct, it is of type *BookInfo. And the type of BookInfo.Meta field is also a pointer, it is of type *TableMeta, thus a *BookInfo can then be looked at as **TableMeta, hence the "double" pointer.
It's true that the struct pointer points to its first field, but don't build on it. It's fragile. If you add a field before it, it'll break badly (which will only happen at runtime, no compile time messages due to package unsafe).
So if the value is of type *BookInfo, simply obtain that out of the reflect.Value wrapper, then you can refer to its field like value.Meta, which will be of type *TableMeta. Avoid using package unsafe, especially if it's not needed.

How to pass integer as pointer using interface{} to function

I thought this is a simple thing to do, but I was wrong. I can't pass integer as pointer to function using interface{}.
Example:
var test int
someChange(&test)
fmt.Printf("after function: %d", test)
func someChange(i interface{}) error{
newFunnyValue := 42
i = newFunnyValue
fmt.Printf("hello from someChange now value test is: %d" , i)
return nil //change gone ok, so nil
}
And result:
hello from someChange now value test is: 42
after function: 0
I read that interface{} is similar to void* so above code should work but it's not, why? I want to add that if I pass some object which is a struct, everything works good.
Do I have to wrap int in some struct?
Edit:
https://play.golang.org/p/rg1vabug0P
If you want to observe the change outside of the someChange() function (in the test variable), you must modify the pointed value (assign a new value to it). You're not doing that, you just assign a new value to the i parameter (which is a local variable inside someChange()).
You may obtain the *int pointer from the i interface variable using type assertion, and then you can assign a new value to the pointed value.
Example:
func someChange(i interface{}) error {
newFunnyValue := 42
if p, ok := i.(*int); ok {
*p = newFunnyValue
return nil //change gone ok, so nil
}
return errors.New("Not *int")
}
Testing it:
var test int
someChange(&test)
log.Printf("after function: %d", test)
Output (try it on the Go Playground):
2009/11/10 23:00:00 after function: 42
Note that wrapping the int value or the *int pointer in a struct is unnecessary and it wouldn't make a difference if you're not assigning a new value to the pointed object.
i is still of type interface{} within the func someChange(). You have to cast it during the assignment:
*i.(*int) = 42

Set an interface to nil in Golang

I'm trying to set an internal value of an interface to nil something like the following :
typ := &TYP{InternalState: "filled"}
setNil(typ)
fmt.Printf("Expecting that %v to be nil", typ)
And I need to know how to implement the setNil(typ interface{}) method.
For more details see this code in play.golang.org.
The thing is you don't have an interface value. You have a pointer value, a pointer to a concrete type. That is not the same as an interface value.
If you want to change the value of a variable of any type, you have to pass a pointer to it. This also includes variables of interface type, and also variables of pointer type. This is one of those very rare cases when a pointer to interface{} makes sense (*interface{}), in fact it's inevitable.
But if your function expects an interface and you pass a non-interface value, an interface value will be created implicitly and you could only nil this implicitly created value.
So we have 2 different / distinct cases:
Function to nil an interface{}
func setNilIf(v *interface{}) {
*v = nil
}
Using it:
var i interface{} = "Bob"
fmt.Printf("Before: %v\n", i)
setNilIf(&i)
fmt.Printf("After: %v\n", i)
Output:
Before: Bob
After: <nil>
So it works.
Function to nil a pointer; using unsafe
Actually this is your case. We want to change the value of a variable of pointer type. To accept a pointer to any type, we can use unsafe.Pointer. unsafe.Pointer is a language support, it's a special pointer type which can be converted from and to any pointer type.
We want to accept the address (pointer) of the pointer variable, which is something like **SomeType. To actually be able to assign a new value (nil) to the pointer variable, we have to dereference it (* operator). But unsafe.Pointer cannot be dereferenced, so first we have to convert it to a pointer to pointer to "something", but since we only want to assign nil (which is the same to all pointer types regardless of the type of the pointed value), the "something" doesn't matter, I will just use int, and so I will convert the unsafe.Pointer pointer value to **int.
func setNilPtr(p unsafe.Pointer) {
*(**int)(p) = nil
}
Using it:
typ := &TYP{InternalState: "filled"}
fmt.Printf("Before: %v\n", typ)
setNilPtr(unsafe.Pointer(&typ))
fmt.Printf("After: %v\n", typ)
Output:
Before: &{filled}
After: <nil>
So this one also works. There is still another way using reflection:
Function to nil a pointer; using reflect
You can also nil a pointer using reflection only (reflect package). We still have to pass the address of the variable of pointer type. Note that in this case the type of the parameter will simply be interface{}. And it will contain a dynamic type like **SomeType. Since pointers have zero value nil, we can obtain such a value with reflect.Zero() which we will set using Value.Set():
func setNilPtr2(i interface{}) {
v := reflect.ValueOf(i)
v.Elem().Set(reflect.Zero(v.Elem().Type()))
}
Using it:
typ2 := &TYP{InternalState: "filled"}
fmt.Printf("Before: %v\n", typ2)
setNilPtr2(&typ2)
fmt.Printf("After: %v\n", typ2)
Output:
Before: &{filled}
After: <nil>
So this one also works. Try these on the Go Playground.
But seriously: if you want to nil something, assign nil to it. Do not complicate things unnecessarily.
i = nil
typ = nil

Reflect thinks struct Value is also a ptr?

I have a data structure like this demo. As you can see, foo has an embedded pointer to bar:
type foo struct {
*bar
}
type bar struct {
S []byte
}
And I'm using the reflect package like this:
func test(x interface{}) {
var v = reflect.ValueOf(x)
if v.Kind() == reflect.Struct {
fmt.Println("was a struct")
// panic: reflect: call of reflect.Value.Elem on struct Value
// v = v.Elem()
// panic: reflect: call of reflect.Value.Field on ptr Value
v = v.FieldByName("S")
}
}
func main() {
var f foo
test(f)
fmt.Println(string(f.S))
}
So v.Kind() is recognized as a reflect.Struct, but if I try to treat it like a struct by using .FieldByName("S"), it panics because it thinks v is a ptr.
So then if I try to treat it like a ptr by calling .Elem(), it panics because it thinks v is a struct.
I've tried reflect.Indirect(), as well as a few other things, but I can't figure out how to get the field of an embedded pointer.
Is there a way to get the reflect.Value representation from an embedded pointer to a struct?
Demo: http://play.golang.org/p/n0eea6XW3I
EDIT: Also tried v = v.FieldByName("bar"), but got:
panic: runtime error: invalid memory address or nil pointer dereference
The first thing we need to realize is that the line var f foo is equivalent to f := foo{}. This initializes the internal field bar (of type *bar) to its zero value... nil. The behavior of embedded types and reflect seems to be that it treats the embedded type's fields as fields of the type itself. So when you request v.FieldByName("S") it's trying to find that field in f's member, bar, which is nil.
You're trying to do this (*f.bar).S. (In Go the explicit pointer dereference isn't needed, but it makes my point). Now the question is: if you change is to v.FieldByName("bar") why does it give an error? Same reason.
Look closely at the stack trace, the FieldByName line no longer crashes, the line that crashes is fmt.Println(string(f.S)). Again, semantically you're doing (*f.bar).S. But the member "bar" is nil, so you are, in fact, doing a nil pointer dereference.
You can fix both errors by changing var f foo to f := foo{&bar{}}.
i was getting this error " panic: reflect: call of reflect.Value.Elem on struct Value" bcz of this line "reflect.ValueOf(parameterName).Elem()"
1.When i am using Elem() in reflex ,it means parameterName inside valueOf() should be a pointer to structure
func Search(flight interface{}, key string) string {
val := reflect.ValueOf(flight).Elem()
for i := 0; i < val.NumField(); i++ {
valueField := val.Field(i)
typeField := val.Type().Field(i)
if key == strings.ToLower(typeField.Name) {
return valueField.Interface().(string)
}
}
return ""
}
Now while calling search function my call should be like this!
result := Search(&flights, key)

Convert Value type to Map in Golang?

I'm getting this return value from a function call in the "reflect" package:
< map[string]string Value >.
Wondering if I can access the actual map inside the return value and if so, how?
EDIT:
So this is where I'm making the call which returns the Value object.
It returns [< map[string]string Value >] to which I grab the first object in that array. However, I'm not sure how to convert [< map[string]string Value >] into a regular map.
view_args := reflect.ValueOf(&controller_ref).MethodByName(action_name).Call(in)
Most reflect Value objects can be converted back to a interface{} value using the .Interface() method.
After obtaining this value, you can assert it back to the map you want. Example (play):
m := map[string]int{"foo": 1, "bar": 3}
v := reflect.ValueOf(m)
i := v.Interface()
a := i.(map[string]int)
println(a["foo"]) // 1
In the example above, m is your original map and v is the reflected value. The interface value i, acquired by the Interface method is asserted to be of type map[string]int and this value is used as such in the last line.
To turn the value in a reflect.Value into an interface{}, you use iface := v.Interface(). Then, to access that, you use a type assertion or type switch.
If you know you're getting a map[string]string the assertion is simply m := iface.(map[string]string). If there's a handful of possibilities, the type switch to handle them all looks like:
switch item := iface.(type) {
case map[string]string:
fmt.Println("it's a map, and key \"key\" is", item["key"])
case string:
fmt.Println("it's a string:", item)
default:
// optional--code that runs if it's none of the above types
// could use reflect to access the object if that makes sense
// or could do an error return or panic if appropriate
fmt.Println("unknown type")
}
Of course, that only works if you can write out all the concrete types you're interested out in the code. If you don't know the possible types at compile time, you have to use methods like v.MapKeys() and v.MapIndex(key) to work more with the reflect.Value, and, in my experience, that involves a long time looking at the reflect docs and is often verbose and pretty tricky.

Resources