为什么 Go 中的 bool 类型是 16 字节长?

Why is bool type in Go 16 bytes long?

我正在阅读“围棋之旅”教程,我稍微修改了其中一个示例,发现围棋中 bool 的大小是 16 个字节?! 我是不是没有使用正确的函数来计算这个,还是 bool 的大小真的是 16 个字节?

package main

import "fmt"
import "unsafe"

func do(i interface{}) {
    switch v := i.(type) {
    case int:
        fmt.Printf("Twice %v is %v\n", v, v*2)
    case string:
        fmt.Printf("%q is %v bytes long\n", v, len(v))
    default:
        fmt.Printf("I don't know about type %T, but it's length is: %v bytes!\n", v, unsafe.Sizeof(v))
    }
}

func main() {
    do(21)
    do("hello")
    do(false)
}

输出:

Twice 21 is 42
"hello" is 5 bytes long
I don't know about type bool, but it's length is: 16 bytes!

那16个字节就是interface{}类型的大小。 v 属于 interface{} 类型,其实现类似于一对 2 指针(一个指向动态类型描述符,一个指向动态值)。您可以在此处了解有关界面“内部结构”的更多信息:Russ Cox: Go Data Structures: Interfaces

这是因为在 default 分支中没有“提取”类型,在 default 分支中 v 的类型与 i 的类型相同.

如果你添加这个:

b := false
fmt.Printf("I don't know about type %T, but it's length is: %v bytes!\n",
    b, unsafe.Sizeof(b))

此输出(在 Go Playground 上尝试):

I don't know about type bool, but it's length is: 1 bytes!

所以bool类型的大小是1个字节。

当您对复合类型(包括字符串、切片)使用 unsafe.Sizeof() 时还要注意,它不包括元素引用的内存。有关详细信息,请参阅