英文:
Generic Go function to save bytes into a fixed-size byte array buffer
问题
如何编写一个通用的Go函数将字节推入字节数组?
我想,追加到切片可能不是一个完美的选择,因为数组不应该增长。
然而,该函数应该处理任何数组大小。
我考虑将数组切片化,以便函数接受任何数组大小。
请参考下面的示例。
是否有更简洁的方法?
Play链接:http://play.golang.org/p/Gii9-JM33E
func push(buf []byte, size int, b byte) (int, error) {
max := len(buf)
if max < 1 {
return size, fmt.Errorf("buffer underflow: max=%d char=%d", max, b)
}
if size >= max {
return size, fmt.Errorf("buffer overflow: size=%d max=%d char=%d", size, max, b)
}
buf[size] = b
return size + 1, nil
}
用法:
buf := [3]byte{}
size := 0
var err error
size, err = push(buf[:], size, 'a')
英文:
How do I to write a generic Go function to push bytes into a byte array?
I suppose appending to a slice is not a perfect fit, because the array should not grow.
However the function should handle any array size.
I am considering to slice the array just to make the function accept any array size.
See my sketch below.
Is there a cleaner way?
Play: http://play.golang.org/p/Gii9-JM33E
func push(buf []byte, size int, b byte) (int, error) {
max := len(buf)
if max < 1 {
return size, fmt.Errorf("buffer underflow: max=%d char=%d", max, b)
}
if size >= max {
return size, fmt.Errorf("buffer overflow: size=%d max=%d char=%d", size, max, b)
}
buf[size] = b
return size + 1, nil
}
Usage:
buf := [3]byte{}
size := 0
var err error
size, err = push(buf[:], size, 'a')
答案1
得分: 2
你几乎肯定想使用切片而不是数组。切片有三个属性:底层支持的数组、容量和长度。容量“cap”告诉你底层数组的大小。
因此,你可以在检查len(s) < cap(s)
之后使用append
来避免重新分配。或者如果你想要一个函数,可以像这样写:
func pushByte(s []byte, b byte) ([]byte, error) {
if len(s) == cap(s) {
return s, errors.New("capacity reached")
}
return append(s, b), nil
}
你可以像这样使用它:
s := make([]byte, 0, 10)
var err error
if s, err = pushByte(s, 10); err != nil {
... 处理错误
}
英文:
You almost certainly want to use a slice instead of an array. A slice has three things: an underlying backing array, a capacity, and a length. The capacity "cap
" tells you the size of the underlying backing array.
So, you can use append
after checking that len(s) < cap(s)
to avoid any reallocation. Or if you want to make a function, perhaps something like this:
func pushByte(s []byte, b byte) ([]byte, error) {
if len(s) == cap(s) {
return s, errors.New("capacity reached")
}
return append(s, b), nil
}
You'd use it something like this:
s := make([]byte, 0, 10)
var err error
if s, err = pushByte(s, 10); err != nil {
... handle error
}
答案2
得分: 1
数组的大小是其类型的一部分。
如果你知道你将要接受的一组大小,你可以使用buf interface{}
并在你想要的大小上进行类型切换。我假设你知道数组的大小,因为它们必须在编译时是常量。
除此之外,你需要使用反射来实际找到数组的大小,并在数组中存储元素。
很少需要使用数组而不是切片。你可能需要重新考虑为什么必须传递不同大小的数组。
英文:
The size of an array is part if its type.
If there's a set of sizes you know you are going to accept, you could take a buf interface{}
with a type switch on the sizes you want. I would assume you know the array sizes, since they must be constant at compile time.
Other than that you would need to use reflection to actually find the array size, and store elements within the array.
It's very infrequent you need to use an array instead of a slice. You may want to reconsider why you have to pass arrays of varying sizes around.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论