use*_*499 3 arrays type-conversion go slice
我有256位存储在一个[32]byte.
我想将其转换为a [8]uint32,第一个uint32存储前四个字节,等等.
我打算写一个函数,通过将位移到正确的位置等来实现这一点,我想知道在Go中是否有更简单的方法可以做到这一点?
binary.ByteOrder该encoding/binary包使其变得简单,binary.ByteOrder接口类型的值可用于uint32从字节切片读取值.有一个binary.LittleEndian导出的变量,你可以开箱即用.把它放在一个简单的for循环中来读取所有8个值:
data := [32]byte{1, 0, 0, 0, 2}
ints := [8]uint32{}
for i := 0; i < len(data); i += 4 {
ints[i/4] = binary.LittleEndian.Uint32(data[i:])
}
fmt.Println(ints)
Run Code Online (Sandbox Code Playgroud)
输出(在Go Playground上试试):
[1 2 0 0 0 0 0 0]
Run Code Online (Sandbox Code Playgroud)
这当然适用于任意数量的字节(4的倍数),而不仅仅是32.
binary.Read()另一个甚至更短的替代方案是使用binary.Read():
func Read(r io.Reader, order ByteOrder, data interface{}) error
Run Code Online (Sandbox Code Playgroud)
这当然需要io.Reader您可以使用的bytes.NewBuffer().这种转换方式很简单:
data := [32]byte{1, 0, 0, 0, 2}
ints := [8]uint32{}
err := binary.Read(bytes.NewBuffer(data[:]), binary.LittleEndian, &ints)
fmt.Println(ints, err)
Run Code Online (Sandbox Code Playgroud)
输出(在Go Playground上试试):
[1 2 0 0 0 0 0 0] <nil>
Run Code Online (Sandbox Code Playgroud)
unsafe.Pointer为了完整起见,这是另一种不安全的方式.由于数组按顺序排列在内存中,因此两个数组都占用相同的大小.我们可以将输入的内存区域解释为输出类型的值:
data := [32]byte{1, 0, 0, 0, 2}
ints := [8]uint32{}
ints = *(*[8]uint32)((unsafe.Pointer)(&data))
fmt.Println(ints)
Run Code Online (Sandbox Code Playgroud)
输出(在Go Playground上试试):
[1 2 0 0 0 0 0 0]
Run Code Online (Sandbox Code Playgroud)
这是解决任务的最有效和最不安全的方法.
在这种情况下,可以像呈现一样安全,但unsafe请谨慎使用包装并作为最后的手段.许多其他看似非常相似的案例可能无效.我们"幸运",因为我们有数组和输入以小端字节顺序给出,但是使用切片和/或不同的字节顺序,它将是一个不同的故事.上面介绍的其他两种方法更为通用,可用于切片和数组.
| 归档时间: |
|
| 查看次数: |
371 次 |
| 最近记录: |