Go中的sizeof结构

Jör*_*chs 20 struct sizeof go

我正在看看Go,看起来很有前途.我试图弄清楚如何获得go结构的大小,例如类似的东西

type Coord3d struct {
    X, Y, Z int64
}
Run Code Online (Sandbox Code Playgroud)

当然我知道它是24个字节,但我想以编程方式知道它...

你有什么想法怎么做?

Rog*_*erV 33

import unsafe "unsafe"

/* Structure describing an inotify event.  */
type INotifyInfo struct {
    Wd     int32  // Watch descriptor
    Mask   uint32 // Watch mask
    Cookie uint32 // Cookie to synchronize two events
    Len    uint32 // Length (including NULs) of name
}

func doSomething() {
    var info INotifyInfo
    const infoSize = unsafe.Sizeof(info)
    ...
}
Run Code Online (Sandbox Code Playgroud)

注意: OP错了.unsafe.Sizeof在示例Coord3d结构上返回24.见下面的评论.

  • OP特别说"我试过`unsafe.Sizeof`并且它不起作用." (2认同)

Sal*_*ali 27

Roger已经展示了如何使用不安全包中的SizeOf方法.请确保在依赖函数返回的值之前阅读此内容:

大小不包括x可能引用的任何内存.例如,如果x是切片,则Sizeof返回切片描述符的大小,而不是切片引用的内存大小.

除此之外,我想解释一下如何使用几个简单的规则轻松计算任何结构的大小.然后如何使用有用的服务验证您的直觉.


大小取决于它所包含的类型和结构中字段的顺序(因为将使用不同的填充).这意味着具有相同字段的两个结构可以具有不同的大小.

例如,此结构的大小为32

struct {
    a bool
    b string
    c bool
}
Run Code Online (Sandbox Code Playgroud)

稍微修改将有24大小(25%的差异只是由于更紧凑的字段排序)

struct {
    a bool
    c bool
    b string
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述 在此输入图像描述

从图片中可以看出,在第二个示例中,我们删除了其中一个填充并移动了一个字段以利用之前的填充.对齐可以是1,2,4或8.填充是用于填充变量以填充对齐的空间(基本上是浪费的空间).

知道这条规则并记住:

  • bool,int8/uint8取1块
  • int16,uint16 - 2块
  • int32,uint32,float32 - 4块
  • int64,uint64,float64,指针 - 8个块
  • 字符串 - 16个块(8个块的2个对齐)
  • 任何切片需要24个块(8个块的3个对齐).所以[]bool,[][][]string是一样的(不要忘记重读我在开头添加的引文)
  • 长度数组n需要n*类型的块.

有了填充,对齐和块的知识,您可以快速找出如何改进您的结构(但仍然有必要使用该服务验证您的直觉).

  • 答案中链接的服务似乎已关闭。 (3认同)
  • 一个结构体持有另一个结构体怎么样——比如“sync.Mutex”?关于订购。 (2认同)

Eva*_*haw 7

binary.TotalSize也是一个选项,但请注意,它与unsafe.Sizeof之间的行为略有不同:binary.TotalSize包含切片内容的大小,而unsafe.Sizeof仅返回顶级描述符的大小.以下是如何使用TotalSize的示例.

package main

import (
    "encoding/binary"
    "fmt"
    "reflect"
)

type T struct {
    a uint32
    b int8
}

func main() {
    var t T
    r := reflect.ValueOf(t)
    s := binary.TotalSize(r)

    fmt.Println(s)
}
Run Code Online (Sandbox Code Playgroud)

  • `binary.Size` 与 `unsafe.Sizeof` [完全不同](https://play.golang.org/p/5qPsFRmFKI),并且存在的原因完全不同。这根本不是OP所要求的。 (3认同)