0

I am going through the "A Tour of Go" tutorial and I modified one of the examples a bit to find that the size of bool in Go is 16 bytes?! Am I not using the correct function to calculate this or is it really that the size of bool is 16 bytes?

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)
}

Output:

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

1 Answers1

6

That 16 bytes is the size of the interface{} type. v is of type interface{} which is implemented something like a pair of 2 pointers (one to the dynamic type descriptor and one to the dynamic value). You can learn more about interface "internals" here: Russ Cox: Go Data Structures: Interfaces

This is because in the default branch there is no "extracted" type, in the default branch type of v is identical to the type of i.

If you add this:

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

This outputs (try it on the Go Playground):

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

So the size of the bool type is 1 byte.

Also beware when you use unsafe.Sizeof() for composite types (strings, slices included), it does not include memory referred to by elements. For details see How to get memory size of variable in Go?

icza
  • 389,944
  • 63
  • 907
  • 827
  • Wait..I thought "i" is of type interface{} and "v" is the extracted value out of it, isn't that right? – Vallerious Sep 01 '20 at 11:07
  • @Vallerious Yes, that's right, but in the `default` branch it is of type `interface{}` (more specifically it's the same as the type of `i`). – icza Sep 01 '20 at 11:10
  • Every value in Go has a specific type defined at compile time. `v` cannot be "whatever type the value of `i` really is", it has to be a well-defined type; in this case, `interface{}`. – Adrian Sep 01 '20 at 15:14