通用Go函数可将字节保存到固定大小的字节数组缓冲区中

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

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.

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
}