【问题标题】:What is the difference between struct{a int;b int} and struct{b int;a int}?struct{a int;b int} 和 struct{b int;a int} 有什么区别?
【发布时间】:2014-10-19 22:51:19
【问题描述】:

这两个结构除了不被视为等效之外,还有什么区别?

package main
func main() {}
func f1(s struct{a int;b int}) { f2(s) }
func f2(s struct{b int;a int}) {}

$ go run a.go 
# command-line-arguments
./a.go:3: cannot use s (type struct { a int; b int }) as type struct { b int; a int } in argument to f2

注意:这个确实编译:

package main
func main() {}
func f1(s struct{a int;b int}) { f2(s) }
func f2(s struct{a int;b int}) {}

【问题讨论】:

    标签: types go


    【解决方案1】:

    “结构字段的顺序在底层很重要”如何?

    这会影响反射,例如func (v Value) Field(i int) Value

    Field 返回结构体 v 的第 i 个字段

    第一个结构中的第一个字段“a”与第二个结构中的第一个字段不同。
    这也会影响marshaler methods (encoding package)序列化

    【讨论】:

      【解决方案2】:

      类型和值的属性

      Type identity

      如果两个结构类型具有相同的序列,则它们是相同的 字段,并且如果对应的字段具有相同的名称,并且相同 类型和相同的标签。

      对应的字段名称不同:

      s struct{a int;b int}
      

      s struct{b int;a int}
      

      【讨论】:

        【解决方案3】:

        来自spec

        两个结构类型是相同的如果它们具有相同的字段序列,并且如果相应的字段具有相同的名称、相同的类型和相同的标签。两个匿名字段被认为具有相同的名称。来自不同包的小写字段名称总是不同的。

        结构体字段的顺序在底层很重要,因此不能安全地将具有不同字段顺序的两个结构体视为等效。

        【讨论】:

        • "结构字段的顺序在底层很重要" 怎么样?
        • Struct packing 和一些形式的数据序列化浮现在脑海中。运行中的 struct 打包示例:play.golang.org/p/gc6jY6541a。另见Data structure alignment on Wikipedia
        • 请注意,Go 的规范绝不保证低级内存按字段顺序布局。虽然不太可能,但编译器完全重新排列每个字段是完全合法的(例如,如果编译器想要以某种方式打包字段以最大化内存效率)。所有规范保证是语义程序员可以在 Go 本身中将它们视为命名字段的有序序列。
        猜你喜欢
        • 2010-10-11
        • 2014-10-20
        • 2023-01-24
        • 1970-01-01
        • 2015-03-20
        • 2016-05-24
        • 1970-01-01
        • 2020-05-05
        • 2019-12-18
        相关资源
        最近更新 更多