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

时间:2014-05-30 14:24:47

标签: arrays go slice

如何编写通用Go函数将字节推送到字节数组?

我认为附加切片不是完美的选择,因为数组不应该增长。 但是该函数应该处理任何数组大小。 我正在考虑切片数组只是为了使函数接受任何数组大小。 请参阅下面的草图。

有更清洁的方式吗?

播放: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')

2 个答案:

答案 0 :(得分:2)

您几乎肯定想要使用切片而不是数组。切片有三个东西:底层支持数组,容量和长度。容量“cap”告诉您底层后备阵列的大小。

因此,您可以在检查append后使用len(s) < cap(s)以避免重新分配。或者如果你想创建一个函数,可能是这样的:

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 {
    ... handle error
}

答案 1 :(得分:1)

数组的大小是其类型的一部分。

如果您知道要接受一组尺寸,则可以使用所需尺寸的buf interface{}类型开关。我假设您知道数组大小,因为它们在编译时必须是常量。

除此之外,你需要使用反射来实际找到数组大小,并在数组中存储元素。

很少需要使用数组而不是切片。您可能需要重新考虑为什么必须传递不同大小的数组。