go - Why is reflection working with UNEXPORTED Struct and Unexported Fields? -
i expected in code work struct dish exported dish. expected program fail when structure dish unexported , not see unexported field within it. (ok, see unexported field being present in exported structure, seems wrong).
but program still works shown?? how can reflection package see 'dish' if unexported?
--------------program follows---------- //modified example blog: http://merbist.com/2011/06/27/golang-reflection-exampl/
package main import ( "fmt" "reflect" ) func main() { // iterate through attributes of data model instance 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 use go's reflection // print attributes of data model func attributes(m interface{}) map[string]reflect.type { typ := reflect.typeof(m) // if pointer struct passed, type of dereferenced object if typ.kind() == reflect.ptr { typ = typ.elem() } // create attribute data structure map of types keyed string. attrs := make(map[string]reflect.type) // structs supported return empty result if passed object // isn't struct if typ.kind() != reflect.struct { fmt.printf("%v type can't have attributes inspected\n", typ.kind()) return attrs } // loop through struct's fields , set map := 0; < typ.numfield(); i++ { p := typ.field(i) fmt.println("p = ", p) if !p.anonymous { attrs[p.name] = p.type } } return attrs }
from: https://blog.golang.org/laws-of-reflection
the field names of t upper case (exported) because exported fields of struct settable."
this shows , proves concept:
fmt.printf("can set 'last'? %v; can set 'id'? %v", reflect.valueof(&dish{}).elem().fieldbyname("last").canset(), reflect.valueof(&dish{}).elem().fieldbyname("id").canset(), )
this prints: can set 'last'? false; can set 'id'? true
on visibility of type (struct) name ("dish" vs "dish") affects visibility when directly use type @ compile time. example:
import "whatever/something" ... v := something.somestruct{} // give compile error ... // can return instance of somestruct, can inspected // reflect other struct (and works fine because // haven't directly put literal "something.somestruct" in code v := something.somefunc()
Comments
Post a Comment