将[]字节转换为[32]字节在内存中而不复制数据

时间:2018-06-03 15:26:22

标签: arrays go slice

我希望在Go中将[]byte转换为[32]byte。最好的方法是什么?我想在内存中引用相同的数组,所以我没有复制数据

这是我提出的最好的,但它复制数据......

var array []byte
var array32 [32]byte
copy(array32[:], array)

2 个答案:

答案 0 :(得分:2)

  

我希望在Go中将[]byte转换为[32]byte。我想参考一下   内存中相同的[底层]数组,所以我没有复制数据。

您正在寻找一些非常不安全的事情。要引用基础数组的字节切片,请使用字节数组指针。例如,

package main

import (
    "fmt"
    "unsafe"
)

func byte32(s []byte) (a *[32]byte) {
    if len(a) <= len(s) {
        a = (*[len(a)]byte)(unsafe.Pointer(&s[0]))
    }
    return a
}

func main() {
    var (
        s []byte    // slice
        a *[32]byte // pointer to array
    )

    s = make([]byte, 32)
    a = byte32(s)
    s[0], a[1] = 42, 39
    fmt.Println(s[0], s[1], s)
    fmt.Println(a[0], a[1], *a)
}

输出:

42 39 [42 39 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
42 39 [42 39 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

答案 1 :(得分:1)

语言规范不允许您直接访问&#34;&#34;切片的底层后备数组。您可以使用包unsafe在peterSO的答案中看到,但正如其名称提示的那样:它不安全

但是,如果允许使用/传递自己的切片,则可以通过切片数组创建切片来访问其支持数组。这不需要任何魔法,slicing expressions如果应用于数组则完全相同:生成的切片将使用切片操作数(数组)作为其后备数组。

例如:

var a [32]byte
s := a[:]

a[0] = 1
fmt.Println(a)
fmt.Println(s)

s[1] = 2
fmt.Println(a)
fmt.Println(s)

输出(在Go Playground上尝试):

[1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

a是一个数组,s是一个切片。通过其中任何一个修改元素,&#34;两者&#34;会同时改变。 sa作为其支持数组,s引用a