🎓 A1Learner
🔍
0 of 28 lessons completed

Go Unsafe Sizes

Unsafe sizes are byte counts that the unsafe package reports for types and values. unsafe.Sizeof tells how much memory a value takes, and unsafe.Offsetof tells where a field starts inside its struct.

Sizes of three values

unsafe.Sizeof reports the byte size of each value passed to it. An int, a string and a slice print their sizes in order.

package main

import (
	"fmt"
	"unsafe"
)

func main() {
	var n int
	var s string
	var list []int
	fmt.Println(unsafe.Sizeof(n), unsafe.Sizeof(s), unsafe.Sizeof(list))
}

A struct size and a field offset

Pair holds an int32 and then an int64. Padding after the first field makes the second field start at byte 8.

package main

import (
	"fmt"
	"unsafe"
)

type Pair struct {
	A int32
	B int64
}

func main() {
	fmt.Println(unsafe.Sizeof(Pair{}))
	fmt.Println(unsafe.Offsetof(Pair{}.B))
}

Field order changes the size

Wide spreads its two bool fields around an int64, and padding grows it to 24 bytes. Slim groups the bool fields after the int64 and stays at 16 bytes.

package main

import (
	"fmt"
	"unsafe"
)

type Wide struct {
	A bool
	B int64
	C bool
}

type Slim struct {
	A int64
	B bool
	C bool
}

func main() {
	fmt.Println(unsafe.Sizeof(Wide{}))
	fmt.Println(unsafe.Sizeof(Slim{}))
}

Example

package main

import (
	"fmt"
	"unsafe"
)

func main() {
	var b bool
	var n int32
	var f float64
	var word string
	fmt.Println("bool:", unsafe.Sizeof(b))
	fmt.Println("int32:", unsafe.Sizeof(n))
	fmt.Println("float64:", unsafe.Sizeof(f))
	fmt.Println("string:", unsafe.Sizeof(word))
}

Key points

  • Use unsafe.Sizeof to read the size in bytes of a value or a type.
  • An int takes 8 bytes, a string takes 16 bytes, and a slice takes 24 bytes.
  • unsafe.Offsetof gives the byte position where a field starts in its struct.
  • The compiler may add padding bytes between fields so each field starts at a neat offset.
  • Grouping small fields together can make a struct smaller.

In this example, four values print their sizes with labels. A bool takes one byte and an int32 takes four bytes. A float64 takes eight bytes, and a string takes sixteen bytes.

Note

Sizes and offsets are safe facts to print, because they never change between runs.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Go Playground

Exercise

Why does the Wide struct take 24 bytes while Slim takes 16?