I am trying to send some data to OpenGl. Sending an array is easy thanks to Sizeof:
array := [...]Whatever {lots of data}
array_ptr := gl.Pointer(&array[0])
array_size := gl.Sizeiptr(unsafe.Sizeof(array))
gl.BufferData(gl.ARRAY_BUFFER, array_size, array_ptr, gl.STATIC_DRAW)
I would like to use slices instead of arrays because the size of my 3D models is not known at compile time.
How do I retrieve the size, in bytes, of the content of a slice? I thought of this:
size := uintptr(len(slice)) * unsafe.Sizeof(slice[0])
but it is not very general. Indeed, I need to know the underlying type of the slice in order for this to work, and this supposes that all the elements of the array have the same size.
I could also loop over the whole slice and add all the sizes of every element. It's not very fast.
I am ready to always keep the len(s)==cap(s), can that help me?
Edit: implementation of the proposed solution using runtime reflection
package main
import "fmt"
import "reflect"
func ElemSize(container interface{}) uintptr {
return reflect.TypeOf(container).Elem().Size()
}
func ElemSizeVerbose(container interface{}) uintptr {
t := reflect.TypeOf(container)
e := t.Elem()
s := e.Size()
fmt.Println(t, e, s)
return s
}
func main() {
a := [...]int8{2, 3, 5, 7, 11} // Array
s := []int64{2, 3, 5, 7, 11} // Slice
z := []int32{} // Even empty things
ElemSizeVerbose(a) // [5]int8 int8 1
ElemSizeVerbose(s) // []int64 int64 8
ElemSizeVerbose(z) // []int32 int32 4
}
A slice has both a length and a capacity. The length of a slice is the number of elements it contains. The capacity of a slice is the number of elements in the underlying array, counting from the first element in the slice. The length and capacity of a slice s can be obtained using the expressions len(s) and cap(s) .
Byte slices are a list of bytes that represent UTF-8 encodings of Unicode code points . Taking the information from above, we could create a byte slice that represents the word “Go”: bs := []byte{71, 111}
To get length of slice in Go programming, call len() function and pass the slice as argument to it. len() function returns an integer, the length of slice. The function returns an integer value, representing the length of given slice.
Slice is a variable-length sequence which stores elements of a similar type, you are not allowed to store different type of elements in the same slice. It is just like an array having an index value and length, but the size of the slice is resized they are not in fixed-size just like an array.
In a slice or array, every element is always the same size. Therefore, your example will work as long as len(s) > 0. In other words, as long as the slice has at least one element in it. Otherwise it will panic.
To avoid the need of having an element in the slice, I recommend using the following:
uintptr(len(s)) * reflect.TypeOf(s).Elem().Size()
you can use (size) of the encoding/binary package.
package main
import (
"encoding/binary"
"fmt"
)
func main() {
a := [...]int8{2, 3, 5, 7, 11} // Array
s := []int64{2, 3, 5, 7, 11} // Slice
z := []int32{} // Even empty things
fmt.Println(binary.Size(a)) // 5
fmt.Println(binary.Size(s)) // 40
fmt.Println(binary.Size(z)) // 0
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With