切片内容的字节大小

huangapple go评论75阅读模式
英文:

Size in bytes of the content of a 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)

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

**如何获取切片内容的大小(以字节为单位)?**我想到了这个方法:

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

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

我也可以遍历整个切片并添加每个元素的大小。但这不是很快。

我准备始终保持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} // 数组
    s := []int64{2, 3, 5, 7, 11} // 切片
    z := []int32{} // 即使是空的
    ElemSizeVerbose(a) // [5]int8 int8 1
    ElemSizeVerbose(s) // []int64 int64 8
    ElemSizeVerbose(z) // []int32 int32 4
}
英文:

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
}

答案1

得分: 8

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

为了避免需要在切片中有一个元素,我建议使用以下方法:

 uintptr(len(s)) * reflect.TypeOf(s).Elem().Size()
英文:

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()

答案2

得分: 3

你可以使用encoding/binary包的Size函数。

package main

import (
	"encoding/binary"
	"fmt"
)

func main() {
	a := [...]int8{2, 3, 5, 7, 11} // 数组
	s := []int64{2, 3, 5, 7, 11}   // 切片
	z := []int32{}                 // 即使是空的也可以

	fmt.Println(binary.Size(a)) // 5
	fmt.Println(binary.Size(s)) // 40
	fmt.Println(binary.Size(z)) // 0
}
英文:

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
}

huangapple
  • 本文由 发表于 2013年2月5日 07:40:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/14697771.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定