5

Как присвоить строку массиву байтов

14

Заголовок: Как преобразовать строку в массив байт в Go?

Текст проблемы:

Я хочу назначить строку массиву байт в Go. У меня есть следующий код:

var arr [20]byte
str := "abc"
for k, v := range []byte(str) {
    arr[k] = byte(v)
}

Однако я ищу другой способ сделать это более эффективно или элегантно. Есть ли альтернативные методы для преобразования строки в массив байт?

5 ответ(ов)

8

Чтобы перевести строку в срез байтов в языке Go, вы можете использовать следующий простой и безопасный способ:

data := []byte("Here is a string....")

Этот код создает срез байтов data, который содержит байты, представляющие строку "Here is a string....". Такой подход обеспечивает конвертацию строки в срез байтов без дополнительных сложностей.

1

Ваш код на Go показывает, как скопировать строку в массив байтов. Давайте разберем его шаг за шагом.

package main

import "fmt"

func main() {
    s := "abc"
    var a [20]byte
    copy(a[:], s)
    fmt.Println("s:", []byte(s), "a:", a)
}

Вы сначала определяете строку s с значением "abc". Затем вы создаете массив a из 20 байтов. Функция copy используется для копирования содержимого строки s в массив a. Важно отметить, что при преобразовании строки в байты, каждый символ в строке представляется в кодировке UTF-8, что соответствует их ASCII-кодам. В данном случае:

  • 'a' соответствует 97,
  • 'b' соответствует 98,
  • 'c' соответствует 99.

Вывод программы:

s: [97 98 99] a: [97 98 99 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

Как видно из вывода, ваша строка преобразуется в массив байтов [97 98 99], а в массиве a находятся эти же значения, после которых идут нули, так как массив a был инициализирован с нулевыми значениями по умолчанию.

Это поведение объясняется тем, что массив a имеет фиксированный размер 20 байтов. Когда выполняется копирование, в массив a помещаются только первые три байта (т.е. значения символов a, b и c), а остальные места остаются нулевыми.

0

Конечно! Если вы хотите создать массив байтов в Go с использованием строки "That's all folks!!", вы можете сделать это следующим образом:

arr := []byte("That's all folks!!")

В этом коде arr будет представлять собой срез байтов, который содержит данные из строки. Использование []byte() преобразует строку в массив байтов, что может быть полезно, например, для работы с бинарными данными или при необходимости модификации отдельных байтов в строке.

0

Ваш код в целом корректен, но есть один нюанс, который следует учесть. Когда вы создаете срез байтов mySlice из строки str, и затем выводите его с помощью fmt.Printf, результат будет отображаться как массив байтов, а не как строка. Чтобы получить корректный вывод строки, вам следует использовать %s для отображения mySlice. Вот исправленный пример:

package main

import "fmt"

func main() {
    str := "abc"
    mySlice := []byte(str)
    fmt.Printf("%v -> '%s'\n", mySlice, string(mySlice))
}

В этом варианте мы оборачиваем mySlice в string(mySlice), чтобы корректно отобразить его как строку. Теперь вывод будет выглядеть как abc -> 'abc'. Вы можете протестировать код по приведенной вами ссылке: http://play.golang.org/p/vpnAWHZZk7.

0

Если вы ищете быстрый способ выполнить конвертацию между срезами с использованием unsafe, обратите внимание на следующее сравнение.

package demo_test

import (
    "testing"
    "unsafe"
)

var testStr = "hello world"
var testBytes = []byte("hello world")

// Избегаем копирования данных.
func UnsafeStrToBytes(s string) []byte {
    return *(*[]byte)(unsafe.Pointer(&s))
}

// Избегаем копирования данных.
func UnsafeBytesToStr(b []byte) string {
    return *(*string)(unsafe.Pointer(&b))
}

func Benchmark_UnsafeStrToBytes(b *testing.B) {
    for i := 0; i < b.N; i++ {
        _ = UnsafeStrToBytes(testStr)
    }
}

func Benchmark_SafeStrToBytes(b *testing.B) {
    for i := 0; i < b.N; i++ {
        _ = []byte(testStr)
    }
}

func Benchmark_UnSafeBytesToStr(b *testing.B) {
    for i := 0; i < b.N; i++ {
        _ = UnsafeBytesToStr(testBytes)
    }
}

func Benchmark_SafeBytesToStr(b *testing.B) {
    for i := 0; i < b.N; i++ {
        _ = string(testBytes)
    }
}

Запуск тестов:

go test -v -bench="^Benchmark" -run=none

Результат:

cpu: Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz
Benchmark_UnsafeStrToBytes
Benchmark_UnsafeStrToBytes-8    1000000000               0.2465 ns/op
Benchmark_SafeStrToBytes
Benchmark_SafeStrToBytes-8      289119562                4.181 ns/op
Benchmark_UnSafeBytesToStr
Benchmark_UnSafeBytesToStr-8    1000000000               0.2530 ns/op
Benchmark_SafeBytesToStr
Benchmark_SafeBytesToStr-8      342842938                3.623 ns/op
PASS

Как видно из результатов, методы UnsafeStrToBytes и UnsafeBytesToStr обеспечивают значительно более высокую производительность по сравнению с их безопасными аналогами, избегая при этом лишнего копирования данных. Однако стоит помнить, что использование unsafe может привести к неопределенному поведению, если не соблюдать осторожность.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь