Конвертировать [] байт в [32] байт в памяти без копирования данных - PullRequest
0 голосов
/ 03 июня 2018

Я хочу преобразовать []byte в [32]byte в Go.Какой лучший способ?Я хочу сослаться на тот же массив в памяти, поэтому я не копирую данные

Это лучшее, что я придумал, но это копирование данных ...

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

Ответы [ 2 ]

0 голосов
/ 04 июня 2018

Спецификация языка не позволяет вам «напрямую» обращаться к базовому, резервному массиву среза.Вы можете сделать это, как вы можете видеть в ответе peterSO, используя пакет unsafe, но, как подсказывает его название: это небезопасно .

Но если вам разрешеноиспользуя / передавая свои собственные фрагменты, вы можете получить доступ к его массиву резервных копий, если вы создадите фрагмент, разрезая массив.Это не требует никакой магии, выражения среза делают именно это, если применяются к массивам: результирующий срез будет использовать операнд среза (массив) в качестве своего резервного массива.

Например:

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 - это срез.Изменяя элементы с помощью любого из них, «оба» будут меняться одновременно.s имеет a в качестве резервного массива, s ссылки a.

0 голосов
/ 03 июня 2018

Я хочу конвертировать []byte в [32]byte в Go.Я хочу сослаться на тот же [базовый] массив в памяти, поэтому я не копирую данные.


Вы хотите сделать что-то очень небезопасное.Для ссылки на байтовый фрагмент, лежащий в основе массива, используйте указатель байтового массива.Например,

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]
...