切片内容的大小(以字节为单位)

Nir*_*iel 4 go slice

我正在尝试向OpenGl发送一些数据.由于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)
Run Code Online (Sandbox Code Playgroud)

我想使用切片而不是数组,因为我的3D模型的大小在编译时是未知的.

如何检索切片内容的大小(以字节单位) 我想到了这个:

size := uintptr(len(slice)) * unsafe.Sizeof(slice[0])
Run Code Online (Sandbox Code Playgroud)

但它不是很一般.实际上,我需要知道切片的基础类型才能使其工作,并且假设数组的所有元素具有相同的大小.

我也可以遍历整个切片并添加每个元素的所有大小.它不是很快.

我准备保持len(s)== cap(s),这可以帮助我吗?

编辑:使用运行时反射实现建议的解决方案

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
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*erg 5

在切片或数组中,每个元素的大小始终相同.因此,只要len(s)> 0,您的示例就会起作用.换句话说,只要切片中至少有一个元素.否则会引起恐慌.

为了避免在切片中使用元素,我建议使用以下内容:

 uintptr(len(s)) * reflect.TypeOf(s).Elem().Size()
Run Code Online (Sandbox Code Playgroud)