V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
a719114136
V2EX  ›  Go 编程语言

Go 获取结构体未导出(私有)变量

  •  
  •   a719114136 ·
    gojuukaze · 2021-04-19 15:15:16 +08:00 · 1271 次点击
    这是一个创建于 1349 天前的主题,其中的信息可能已经有所发展或是发生改变。

    原文链接 >> Go 获取结构体未导出(私有)变量 www.ikaze.cn

    |
    Go 语音通过首字符的大小写来限制变量、函数的包外可见性。最近遇到个问题,需要访问一个官方包的未导出变量,发现可以通过反射获取,于是记录下来:

    首选我们建个新的包 user/user.go

    package user
    
    type User struct {
    	id   int
    	Name string
    }
    
    func NewUser() User {
    	return User{2, "gojuukaze"}
    }
    

    然后我们编写 main.go ,通过 reflect.ValueOf 输出 user

    func main(){
    	user:= user.NewUser()
    	fmt.Println(user.Name)
    	fmt.Println(reflect.ValueOf(user))
    }
    

    程序的输出为:

    gojuukaze
    {2 gojuukaze}
    

    可以看到reflect.ValueOf其实是能获取未导出的变量的。

    reflect.ValueOf 接下来返回的是结构体Value ,接下来我们查看Value 方法,可以看到一个 FieldByName 函数,从名字不难看出,它是通过字段名获取字段。


    接下来尝试通过FieldByName 获取变量。需要注意的是 FieldByName返回的是Value类型,你可能需要经过类型装换有才能使用。

    func main(){
    	user:= user.NewUser()
    	v:=reflect.ValueOf(user)
    	fmt.Println(v.FieldByName("id"))
    	fmt.Println(v.FieldByName("id").Int())
    }
    

    程序输出为:

    2
    2
    
    2 条回复    2021-04-19 16:18:10 +08:00
    maocat
        1
    maocat  
       2021-04-19 15:25:20 +08:00
    反射还是少用
    qW7bo2FbzbC0
        2
    qW7bo2FbzbC0  
       2021-04-19 16:18:10 +08:00
    熟悉的味道,还是 python 的君子协定好点
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2100 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 01:11 · PVG 09:11 · LAX 17:11 · JFK 20:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.