// A use case to avoid:: panic: reflect.Value.Interface: cannot return 
value obtained from unexported field or method

```
package main

import (
    "fmt"
    "reflect"
    "strings"
    "unsafe"
)

type Person1 struct {
    W3ID string
    Name string
}

type Address1 struct {
    city    string
    country string
}

type User1 struct {
    name      string
    age       int
    address   Address1
    manager   Person1
    developer Person1
    tech      Person1
}

func showDetails(load, email interface{}) {
    //fmt.Println("The values in the first argument are :")
    if reflect.ValueOf(load).Kind() == reflect.Struct {
        typ := reflect.TypeOf(load)
        value := reflect.ValueOf(load)
        value2 := reflect.New(value.Type()).Elem() // #1 For struct, not 
addressable create a copy With Elements.
        value2.Set(value)                          //#2 Value2 is 
addressable and can be set
        for i := 0; i < typ.NumField(); i++ {
            //fmt.Println(value.Field(i).Kind(), "---------")
            if value.Field(i).Kind() == reflect.Struct {
                rf := value2.Field(i)
                rf = reflect.NewAt(rf.Type(), 
unsafe.Pointer(rf.UnsafeAddr())).Elem()
                irf := rf.Interface() 
                typrf := reflect.TypeOf(irf)
                nameP := typrf.String()
                if strings.Contains(nameP, "Person") {
                    //fmt.Println(nameP, "FOUND !!!!!!! ")
                    for j := 0; j < typrf.NumField(); j++ {
                        //fmt.Println(j)
                        re := rf.Field(j)
                        nameW := typrf.Field(j).Name
                        //fmt.Println(nameW)
                        if strings.Contains(nameW, "W3ID") {
                            //fmt.Println(nameW)
                            valueW := re.Interface()
                            fetchEmail := valueW.(string)
                            //fmt.Println(fetchEmail)
                            if fetchEmail == email {
                                fmt.Println(fetchEmail, " MATCH!!!!")
                            }
                        }
                    }
                }
                //fmt.Println(rf.Interface(), "++=====")
                showDetails(irf, email)
            } else {
                // fmt.Printf("%d.Type:%T || Value:%#v\n",
                //     (i + 1), value.Field(i), value.Field(i))

                // fmt.Println("Kind is ", value.Field(i).Kind())
            }
        }
    }
}

func main() {
    iD := "ts...@in.org.com"

    load := User1{
        name: "John Doe",
        age:  34,
        address: Address1{
            city:    "New York",
            country: "USA",
        },
        manager: Person1{
            W3ID: "jb...@in.org.com",
            Name: "Bualt",
        },
        developer: Person1{
            W3ID: "ts...@in.org.com",
            Name: "Sumi",
        },
        tech: Person1{
            W3ID: "lp...@in.org.com",
            Name: "Paul",
        },
    }

    showDetails(load, iD)
}
```
On Tuesday, February 11, 2020 at 7:17:48 PM UTC+5:30 rog wrote:

> On Tue, 11 Feb 2020 at 03:38, Ian Lance Taylor <ia...@golang.org> wrote:
>
>> On Mon, Feb 10, 2020 at 4:15 AM 'Axel Wagner' via golang-nuts
>> <golan...@googlegroups.com> wrote:
>> >
>> > It's reflect, so I don't feel confident in making any absolute 
>> statements (we've talked about it a bunch; I just find the implications of 
>> that API far too unwieldy to handle), but I tend to agree. You need a 
>> reference value and Bytes() seems the only typed reference value you can 
>> get out of reflect.Value without using Interface() and type-assertion. I 
>> don't think this can be fixed either - not just because of compatibility, 
>> but also because it would impede fmt.Print*.
>>
>> https://golang.org/issue/27727.
>>
>
> Ah, thanks! I'd missed that. I added a comment there FWIW.
>  
>
>>
>> Ian
>>
>> > On Mon, Feb 10, 2020 at 11:46 AM roger peppe <rogp...@gmail.com> wrote:
>> >>
>> >> On Sun, 9 Feb 2020 at 00:19, 'Axel Wagner' via golang-nuts <
>> golan...@googlegroups.com> wrote:
>> >>>
>> >>> (then again, the fact that this works seems slightly concerning to 
>> me: https://play.golang.org/p/phWQ83wPQtx)
>> >>
>> >>
>> >> Oh, that's interesting! Is this the only way that you can use reflect 
>> (without unsafe) to modify the contents of unexported fields?
>> >> I think it might be.
>> >>
>> > --
>> > You received this message because you are subscribed to the Google 
>> Groups "golang-nuts" group.
>> > To unsubscribe from this group and stop receiving emails from it, send 
>> an email to golang-nuts...@googlegroups.com.
>> > To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/CAEkBMfG%3Di%2BPgKBfsNPtWNZXMzQV2AAqk%3DnQuo7Oi_pabXcJQEA%40mail.gmail.com
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/4477c45a-3a14-439e-b085-185efb1cdc3cn%40googlegroups.com.

Reply via email to