关于go:切片内容的大小(以字节为单位)

Size in bytes of the content of a slice

我正在尝试向OpenGL发送一些数据。通过sizeof,发送阵列很容易:

1
2
3
4
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)

我想用切片代替数组,因为我的三维模型的大小在编译时是未知的。

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

1
size := uintptr(len(slice)) * unsafe.Sizeof(slice[0])

但它不是很一般。实际上,我需要知道切片的底层类型,这样才能工作,并且假设数组的所有元素都具有相同的大小。

我还可以循环整个切片,并添加每个元素的所有大小。不是很快。

我随时准备好保持长度等于上限,这对我有帮助吗?

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
}


在一个切片或数组中,每个元素的大小总是相同的。因此,只要len(s)>0,您的示例就可以工作。换句话说,只要切片中至少有一个元素。否则它会恐慌。

为了避免在切片中包含元素,我建议使用以下方法:

1
 uintptr(len(s)) * reflect.TypeOf(s).Elem().Size()


您可以使用编码/二进制包的(大小)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
}