Reputation: 13865
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')
Upvotes: 0
Views: 1813
Reputation: 58409
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
}
Upvotes: 2
Reputation: 109475
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.
Upvotes: 1