Why does reflection work with UNEXPORTED Struct and Unexported Fields?

I expected that in the code for working with struct Dish was EXPORTED as a Dish. I expected that the program would fail if the plate structure was not expanded and did not see an unexposed field in it. (OK, I could see that the region with the outstanding data is present in the EXPORTED STRUCTURE, but even this seems to be wrong).

But is the program still working as shown? How can a reflection packet see a “dish” if it is not shown?

-------------- The program is running ---------- // Modified example From the blog: http://merbist.com/2011/06/27/golang-reflection -exampl /

package main

import (
    "fmt"
    "reflect"
)

func main() {
    // iterate through the attributes of a Data Model instance
    for name, mtype := range attributes(&dish{}) {
        fmt.Printf("Name:  %s,  Type:  %s\n", name, mtype)
    }
}

// Data Model
type dish struct {
    Id     int
    last   string
    Name   string
    Origin string
    Query  func()
}

// Example of how to use Go reflection
// Print the attributes of a Data Model
func attributes(m interface{}) map[string]reflect.Type {
    typ := reflect.TypeOf(m)
    // if a pointer to a struct is passed, get the type of the dereferenced object
    if typ.Kind() == reflect.Ptr {
        typ = typ.Elem()
    }

    // create an attribute data structure as a map of types keyed by a string.
    attrs := make(map[string]reflect.Type)
    // Only structs are supported so return an empty result if the passed object
    // isn't a struct
    if typ.Kind() != reflect.Struct {
        fmt.Printf("%v type can't have attributes inspected\n", typ.Kind())
        return attrs
    }

    // loop through the struct fields and set the map
    for i := 0; i < typ.NumField(); i++ {
        p := typ.Field(i)
        fmt.Println("P = ", p)
        if !p.Anonymous {
            attrs[p.Name] = p.Type
        }
    }

    return attrs
}
+4
source share
1

: https://blog.golang.org/laws-of-reflection

T (), .

:

fmt.Printf("can set 'last'? %v; can set 'Id'? %v",
    reflect.ValueOf(&dish{}).Elem().FieldByName("last").CanSet(),
    reflect.ValueOf(&dish{}).Elem().FieldByName("Id").CanSet(),
)

: can set 'last'? false; can set 'Id'? true

() ( "" "" ), , . :

import "whatever/something"
...
v := something.someStruct{} // will give compile error
...
// this can return an instance of someStruct, which can be inspected
// with reflect just like any other struct (and that works fine because
// we haven't directly put a literal "something.someStruct" in this code
v := something.SomeFunc()
+1

All Articles