1
package main

import (
    "fmt"
    "reflect"
)

type PetDetails struct {
    Name *string
}

type Student struct {
    Fname  string
    Lname  string
    City   string
    Mobile *int
    Pet *PetDetails
}

func main() {
    i := 7777777777
    petName := "Groot"
    s := Student{"Chetan", "Tulsyan", "Bangalore", &i, &PetDetails{&petName}}
    v := reflect.ValueOf(s)
    typeOfS := v.Type()
    
    for i := 0; i< v.NumField(); i++ {
        fmt.Printf("Field: %s\tValue: %v\n", typeOfS.Field(i).Name, v.Field(i).Interface())
    }
}

I am trying to convert these struct into map[string]string as I need the map for update query of mongoDB. After converting my struct to BSON, instead of querying { "pet.name": "Groot" } it becomes { "pet": { "name": "Groot" } } which deletes other fields inside the embedded document pet. I'm not sure how to override BSON marshals as I'm using mongodb driver, not mgo

I would like to get value of Mobile pointer and Name of the Pet, but all I get is the address

How can I get the value, e.g. 7777 and Groot ? Thanks

nanakondor
  • 429
  • 4
  • 10
  • 3
    Use [`Elem`](https://golang.org/pkg/reflect/#Value.Elem) to de-reference pointers, use [`FieldByName`](https://golang.org/pkg/reflect/#Value.FieldByName) to get to a specific field. https://play.golang.org/p/3hmDL0e1OH6 – mkopriva Sep 18 '20 at 05:41

1 Answers1

0

You can use Elem to dereference the pointer types.

x := 5
ptr := reflect.ValueOf(&x)
value := ptr.Elem()

ptr.Type().Name() // *int
ptr.Type().Kind() // reflect.Ptr
ptr.Interface()   // [pointer to x]
ptr.Set(4)        // panic

value.Type().Name() // int
value.Type().Kind() // reflect.Int
value.Interface()   // 5
value.Set(4)        // this works

For example, to retrieve the mobile number in your example you should change the loop in main to:

for i := 0; i < v.NumField(); i++ {
    field := v.Field(i)
    value := field.Interface()

    // If a pointer type dereference with Elem
    if field.Kind() == reflect.Ptr {
        value = field.Elem().Interface()
    }

    fmt.Printf("Field: %s\tValue: %v\n", typeOfS.Field(i).Name, value)
}
Jem Tucker
  • 1,034
  • 15
  • 29