使用reflect,如何设置结构体字段的值?
使用 reflect
包处理结构字段时遇到了困难。特别是还没弄清楚如何设置字段值。
type t struct { fi int; fs string } var r t = t{ 123, "jblow" } var i64 int64 = 456
获取字段 i 的名称 - 这似乎有效
var field =reflect.TypeOf(r).Field(i).Name
获取字段 i 的值作为 a) interface{}, b) int - 这似乎有效
var iface 接口{} =reflect.ValueOf(r).Field(i).Interface()
var i int = int(reflect.ValueOf(r).Field(i).Int())
设置字段 i 的值 - 尝试一个 - 恐慌
reflect.ValueOf(r).Field(i).SetInt( i64 )
恐慌:reflect.Value·SetInt使用通过未导出字段获得的值
假设它不喜欢字段名称“id”和“name”,因此重命名为“Id”和“Name”
a)这个假设正确吗?
b) 如果正确,认为没有必要,因为在同一个文件/包中
设置字段 i 的值 - 尝试两个(字段名称大写) - 恐慌
reflect.ValueOf(r).Field(i).SetInt(465)
reflect.ValueOf(r).Field(i).SetInt( i64 )
恐慌:reflect.Value·SetInt使用不可寻址的值
@peterSO 下面的说明是彻底且高质量的
四。这有效:
reflect.ValueOf(&r).Elem().Field(i).SetInt( i64 )
他还记录了字段名称必须可导出(以大写字母开头)
having a rough time working with struct fields using reflect
package. in particular, have not figured out how to set the field value.
type t struct { fi int; fs string } var r t = t{ 123, "jblow" } var i64 int64 = 456
getting Name of field i - this seems to work
var field = reflect.TypeOf(r).Field(i).Name
getting value of field i as a) interface{}, b) int - this seems to work
var iface interface{} = reflect.ValueOf(r).Field(i).Interface()
var i int = int(reflect.ValueOf(r).Field(i).Int())
setting value of field i - try one - panic
reflect.ValueOf(r).Field(i).SetInt( i64 )
panic: reflect.Value·SetInt using value obtained using unexported field
assuming it did not like field names "id" and "name", so renamed to "Id" and "Name"
a) is this assumption correct?
b) if correct, thought not necessary since in same file / package
setting value of field i - try two (with field names capitalized ) - panic
reflect.ValueOf(r).Field(i).SetInt( 465 )
reflect.ValueOf(r).Field(i).SetInt( i64 )
panic: reflect.Value·SetInt using unaddressable value
Instructions below by @peterSO are thorough and high quality
Four. this works:
reflect.ValueOf(&r).Elem().Field(i).SetInt( i64 )
he documents as well that the field names must be exportable (begin with capital letter)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Go json 包从 Go 结构编组和解组 JSON。
下面是一个分步示例,它设置
struct
字段的值,同时小心避免错误。Go
reflect
包有一个CanAddr
函数。Go
reflect
包有一个CanSet
函数,如果true
,则意味着CanAddr 也是
真
。我们需要确保我们可以
设置
struct
字段。例如,如果我们可以确定所有错误检查都是不必要的,则该示例可简化为,
顺便说一句,Go 可用为 开源代码。了解反射的一个好方法是看看核心 Go 开发人员如何使用它。例如,Go fmt 和 json 包。包文档在包文件标题下提供了源代码文件的链接。
The Go json package marshals and unmarshals JSON from and to Go structures.
Here's a step-by-step example which sets the value of a
struct
field while carefully avoiding errors.The Go
reflect
package has aCanAddr
function.The Go
reflect
package has aCanSet
function, which, iftrue
, implies thatCanAddr
is alsotrue
.We need to make sure we can
Set
thestruct
field. For example,If we can be certain that all the error checks are unnecessary, the example simplifies to,
BTW, Go is available as open source code. A good way to learn about reflection is to see how the core Go developers use it. For example, the Go fmt and json packages. The package documentation has links to the source code files under the heading Package files.
这似乎有效:
打印:
This seems to work:
Prints:
您可以创建一个辅助函数来设置值:
Playground: https://go.dev/play/p/ uHoy5n3k1DW
You can create a helper function to set values:
Playground: https://go.dev/play/p/uHoy5n3k1DW