简体   繁体   English

使用Go,如何将未知数量的字节追加到向量中并获取字节切片?

[英]With Go, how to append unknown number of byte into a vector and get a slice of bytes?

I'm trying to encode a large number to a list of bytes(uint8 in Go). 我正在尝试将大量编码编码为字节列表(Go中的uint8)。 The number of bytes is unknown, so I'd like to use vector. 字节数未知,因此我想使用向量。 But Go doesn't provide vector of byte, what can I do? 但是Go不提供字节向量,我该怎么办? And is it possible to get a slice of such a byte vector? 并且有可能获得这种字节向量的切片吗?

I intends to implement data compression. 我打算实现数据压缩。 Instead of store small and large number with the same number of bytes, I'm implements a variable bytes that uses less bytes with small number and more bytes with large number. 我实现了一个可变字节,而不是使用相同的字节数存储大小较小的数字,而是使用可变的字节,该变量使用较少的较小字节和较大的字节。

My code can not compile, invalid type assertion: 我的代码无法编译,类型断言无效:

  1 package main
  2 
  3 import (
  4     //"fmt"
  5     "container/vector"
  6 )
  7 
  8 func vbEncodeNumber(n uint) []byte{
  9     bytes := new(vector.Vector)
 10     for {
 11         bytes.Push(n % 128)
 12         if n < 128 {
 13             break
 14         }
 15         n /= 128
 16     }
 17     bytes.Set(bytes.Len()-1, bytes.Last().(byte)+byte(128))
 18     return bytes.Data().([]byte) // <-
 19 }
 20 
 21 func main() { vbEncodeNumber(10000) }

I wish to writes a lot of such code into binary file, so I wish the func can return byte array. 我希望将许多这样的代码写入二进制文件,所以我希望func可以返回字节数组。

I haven't find a code example on vector. 我还没有找到关于vector的代码示例。

Since you're trying to represent large numbers, you might see if the big package serves your purposes. 由于您要表示较大的数字,因此您可能会看到大包装是否符合您的目的。

The general Vector struct can be used to store bytes. 通用Vector结构可用于存储字节。 It accepts an empty interface as its type, and any other type satisfies that interface. 它接受一个空接口作为其类型,其他任何类型都满足该接口。 You can retrieve a slice of interfaces through the Data method, but there's no way to convert that to a slice of bytes without copying it. 您可以通过Data方法检索接口的一部分,但无法在不复制接口的情况下将其转换为字节的一部分。 You can't use type assertion to turn a slice of interface{} into a slice of something else. 您不能使用类型断言来将interface {}的一部分转换为其他内容的一部分。 You'd have to do something like the following at the end of your function: (I haven't tried compiling this code because I can't right now) 您必须在函数结尾处执行以下操作:(我没有尝试编译此代码,因为现在无法这样做)

byteSlice = make([]byte, bytes.Len())
for i, _ := range byteSlice {
    byteSlice[i] = bytes.At(i).(byte)
}
return byteSlice

Take a look at the bytes package and the Buffer type there. 看一下字节包和那里的Buffer类型。 You can write your ints as bytes into the buffer and then you can use the Bytes() method to access byte slices of the buffer. 您可以将int作为字节写入缓冲区,然后可以使用Bytes()方法访问缓冲区的字节片。

I've found the vectors to be a lot less useful since the generic append and copy were added to the language. 由于通用的附加和复制已添加到语言中,因此我发现矢量的用途要少得多。 Here's how I'd do it in one shot with less copying: 这是我减少复制的一次拍摄的方法:

package main

import "fmt"

func vbEncodeNumber(n uint) []byte {
    bytes := make([]byte, 0, 4)
    for n > 0 {
        bytes = append(bytes, byte(n%256))
        n >>= 8
    }
    return bytes
}

func main() {
    bytes := vbEncodeNumber(10000)
    for i := len(bytes)-1; i >= 0 ; i-- {
        fmt.Printf("%02x ", bytes[i])
    }
    fmt.Println("")
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM