【问题标题】:Reflect Type.Field() order反映 Type.Field() 顺序
【发布时间】:2015-11-30 06:33:14
【问题描述】:

我似乎在文档中找不到它,是否可以保证字段中的顺序与结构中声明的顺序相匹配?我知道这似乎是合乎逻辑的(由于内存布局),而且它似乎也以这种方式执行,但只是确保。如果这不是保证,我不希望代码在以后中断。

例如,如果我有

type Foo struct {
    bar    string `tag:"bar"`
    baz    string `tag:"baz"`
    barbaz string `tag:"barbaz"`
}

然后我运行了这段代码:

var c Foo
t := reflect.TypeOf(c)
nf := t.NumField()

tags := make([]string, nf)

for f := 0; f < nf; f++ {
    tags[f] = t.Field(f).Tag.Get("tag")
}

tags 能保证是["bar", "baz", "barbaz"]吗?

【问题讨论】:

  • Value.FieldByName 对您有帮助吗?
  • 我只是想要一些东西的标签名称,更多的是我是一个懒惰的程序员,并试图少写一点代码(这似乎总是变成更多的工作)。我不知道我是否会再坚持这种方法,现在我只是对答案有点兴趣。
  • 即使 GC(标准 Go 编译器)和 GCCGO 不重新编码结构字段,我也不会依赖任何排序。文档中没有明确的保证。
  • 也许这是一个愚蠢的问题,但你怎么知道他们不重新排序结构字段?此外(有可能在评论中提出过多的要求)他们这样做是否会被认为是有利的?我对编译器设计了解不多。
  • 如果您可以通过重新排序字段而不是在它们之间添加填充来实现内存对齐,那将是有利的。

标签: go


【解决方案1】:

我在 golang-nuts 上问过这个问题,得到了an answer from Ian Lance Taylor 确认它的申报顺序,并且不会改变。

【讨论】:

    【解决方案2】:

    即使现在 GC(标准 Go 编译器)和 GCCGO 不重新编码结构字段,我也不会依赖任何排序。文档中没有明确的保证。这可能会在任一编译器的未来版本中完成。

    字段重新排序是一种用于在结构内部对齐字段而不使用填充(不必要地膨胀结构的内存表示)的技术。您可以在以下问题中了解它:

    Why can't C compilers rearrange struct members to eliminate alignment padding?

    【讨论】:

    • 我想补充一点,这不太可能,因为这会破坏很多依赖于内存对齐的东西,但你仍然是正确的。
    猜你喜欢
    • 1970-01-01
    • 2021-06-02
    • 2016-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-19
    • 2015-05-21
    • 1970-01-01
    相关资源
    最近更新 更多