Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inspect slice header?

Tags:

slice

go

This is slightly modified code from slices

var buffer [256] byte

func SubtractOneFromLength(slice []byte) []byte {
    slice = slice[0 : len(slice)-1]
    return slice
}

func main() {
    slice := buffer[10:20]
    fmt.Println("Before: len(slice) =", len(slice))
    newSlice := SubtractOneFromLength(slice)
    fmt.Println("After:  len(slice) =", len(slice))
    fmt.Println("After:  len(newSlice) =", len(newSlice))
    newSlice2 := SubtractOneFromLength(newSlice)
    fmt.Println("After:  len(newSlice2) =", len(newSlice2))
}

It says that contents of a slice argument can be modified by a function, but its header cannot. How can I print header of newSlice2 on my screen?

like image 335
Richard Rublev Avatar asked Jan 15 '19 09:01

Richard Rublev


1 Answers

The slice header is represented by the reflect.SliceHeader type:

type SliceHeader struct {
        Data uintptr
        Len  int
        Cap  int
}

You may use package unsafe to convert a slice pointer to *reflect.SliceHeader like this:

sh := (*reflect.SliceHeader)(unsafe.Pointer(&newSlice2))

And then you may print it like any other structs:

fmt.Printf("%+v", sh)

Output will be (try it on the Go Playground):

&{Data:1792106 Len:8 Cap:246}

Also note that you can access the info stored in a slice header without using package unsafe and reflect:

  • to get the Data field, you may use &newSlice2[0]
  • to get the Len field, use len(newSlice2)
  • to get the Cap field, use cap(newSlice2)

See a modified Go Playground example which shows these values are the same as in the slice header.

See related questions:

How to create an array or a slice from an array unsafe.Pointer in golang?

nil slices vs non-nil slices vs empty slices in Go language

like image 109
icza Avatar answered Dec 03 '22 20:12

icza