绕过Go的反射类型安全系统给未导出的结构体成员赋值
反射的时候尝试给未导出的结构体成员(不管是自己包的、还是别人包的),都不被Go标准库的reflect反射库允许,会直接崩溃。
如下代码,尝试给name反射赋值会runtime panic:
1 2 3 4 5 6 7 8 9 10 |
|
错误如下:
1
|
|
我要用反射给我自己的包的成员赋值,并且不想它们被公开导出。1 难道真没有办法了?有的:unsafe.Pointer一顿操作就完事了,管它“Package unsafe contains operations that step around the type safety of Go programs.”呢。因为这其实是reflect包的软限制,最暴力的办法大不了把reflect拎出来魔改一下就好了,但是我并不想因为一个简单需求就如此大动刀戈。![doge [doge]](/v3/dynamic/emojis/weixin/doge.png)
解法:虽然不让Set,但是是允许取地址(take address) 的,即func UnsafeAddr() uintptr。取到地址后,那我就像C语言一样deref一下就能随便写了。
1 2 3 4 5 6 7 8 9 |
|
非常不unsafe的代码,使劲造吧。![doge [doge]](/v3/dynamic/emojis/weixin/doge.png)
-
真实的需求是:我给我的多个私有结构体成员标注了名为css的tag,我要用反射执行
document.querySelector查DOM树并赋值给它们,减少初始化时手写太多代码。 ^