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

Val*_*ous 0 size boolean go

我正在阅读“A Tour of Go”教程,并对其中一个示例进行了一些修改,发现 Go 中 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)
}
Run Code Online (Sandbox Code Playgroud)

输出:

Twice 21 is 42
"hello" is 5 bytes long
I don't know about type bool, but it's length is: 16 bytes!
Run Code Online (Sandbox Code Playgroud)

icz*_*cza 6

16 字节是类型的大小interface{}v其类型interface{}的实现类似于一对 2 个指针(一个指向动态类型描述符,一个指向动态值)。您可以在这里了解有关接口“内部结构”的更多信息:Russ Cox:Go 数据结构:接口

这是因为在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))
Run Code Online (Sandbox Code Playgroud)

输出(在Go Playground上尝试):

I don't know about type bool, but it's length is: 1 bytes!
Run Code Online (Sandbox Code Playgroud)

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

另请注意,当您使用unsafe.Sizeof()复合类型(包括字符串、切片)时,它不包括元素引用的内存。详细信息请参见Go中如何获取变量的内存大小?