为什么反射与 UNEXPORTED Struct 和 Unexported Fields 一起工作?

God*_*her 5 go

我期望在代码中使用 struct Dish被导出为 Dish。我预计当结构未导出并且看不到其中未导出的字段时,程序会失败。(好吧,我可以看到 EXPORTED STRUCTURE 中存在未导出的字段,但即使这样似乎也是错误的)。

但是程序仍然如图所示??如果未导出,反射包如何看到“dish”?

--------------Program Follows--------- //来自博客的修改示例:http : //merbist.com/2011/06/27/golang-reflection -示例/

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's 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's 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
}
Run Code Online (Sandbox Code Playgroud)

Bra*_*ody 4

来自: 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(),
)
Run Code Online (Sandbox Code Playgroud)

这打印:can set 'last'? false; can set 'Id'? true

关于类型(结构)名称(“dish”与“Dish”)的可见性,仅在编译时直接使用该类型时影响可见性。例如:

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()
Run Code Online (Sandbox Code Playgroud)