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

Popular posts from this blog

Export Excel workseet into txt file using vba - (text and numbers with formulas) -

wordpress - (T_ENDFOREACH) php error -

Using django-mptt to get only the categories that have items -