Как присвоить строку массиву байтов - PullRequest
312 голосов
/ 07 ноября 2011

Я хочу присвоить строку байтовому массиву:

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

Есть другой метод?

Ответы [ 9 ]

473 голосов
/ 01 февраля 2015

Безопасно и просто:

[]byte("Here is a string....")
115 голосов
/ 02 сентября 2016

Для преобразования строки в фрагмент байта, string -> []byte:

[]byte(str)

Для преобразования массива в фрагмент, [20]byte -> []byte:

arr[:]

Для копированиястрока в массив, string -> [20]byte:

copy(arr[:], str)

То же, что и выше, но сначала явно преобразуется строка в фрагмент:

copy(arr[:], []byte(str))

  • Встроенныйв copy функция только копирует в срез, с срез.
  • Массивы - это «базовые данные», в то время как срезы - «область просмотра в базовых данных".
  • Использование [:] делает массив квалифицированным как срез.
  • Строка не относится к срезу, который можно скопировать в , но она квалифицируется какфрагмент, который можно скопировать из (строки неизменны).
  • Если строка слишком длинная, copy скопирует только ту часть строки, которая подходит.

Этот код:

var arr [20]byte
copy(arr[:], "abc")
fmt.Printf("array: %v (%T)\n", arr, arr)

... дает следующий вывод:

array: [97 98 99 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] ([20]uint8)

Я также сделал его доступным на Go Playground

106 голосов
/ 07 ноября 2011

Например,

package main

import "fmt"

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

Вывод:

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]
40 голосов
/ 26 января 2016

кусок пирога:

arr := []byte("That's all folks!!")
24 голосов
/ 12 июля 2013

Я думаю, что лучше ..

package main

import "fmt"

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

Проверьте здесь: http://play.golang.org/p/vpnAWHZZk7

6 голосов
/ 05 ноября 2018

Go, преобразовать строку в фрагмент байта

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

package main

func main() {

    var s string

    //...

    b := []byte(s)

    //...
}

, что полезно при использовании ioutil.WriteFile, который принимает срез байтов в качестве параметра данных:

WriteFile func(filename string, data []byte, perm os.FileMode) error

Другой пример

package main

import (
    "fmt"
    "strings"
)

func main() {

    stringSlice := []string{"hello", "world"}

    stringByte := strings.Join(stringSlice, " ")

    // Byte array value
    fmt.Println([]byte(stringByte))

    // Corresponding string value
    fmt.Println(string([]byte(stringByte)))
}

Выход:

[104 101 108 108 111 32 119111 114 108 100] hello world

Пожалуйста, проверьте ссылку детская площадка

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

Массивы - это значения ... срезы больше похожи на указатели.То есть [n]type не совместимо с []type, поскольку это принципиально две разные вещи.Вы можете получить фрагмент, который указывает на массив, используя arr[:], который возвращает фрагмент, имеющий arr в качестве резервного хранилища.

Один из способов преобразования фрагмента, например []byte в [20]byte, - это фактически выделить [20]byte, что вы можете сделать, используя var [20]byte (так как это значение ... нет make необходимо), а затем скопируйте в него данные:

buf := make([]byte, 10)
var arr [10]byte
copy(arr[:], buf)

По сути, многие другие ответы ошибаются в том, что []type НЕ является массивом.

[n]T и []T - это совершенно разные вещи!

При использовании отражения []T не является массивом Array, но имеет вид Slice, а [n]Tвид массива.

Вы также не можете использовать map[[]byte]T, но вы можете использовать map[[n]byte]T.

Это иногда может быть громоздким, потому что многие функции работают, например, на []byte, тогда как некоторые функции возвращают [n]byte (в особенности хеш-функции в crypto/*).Например, хэш sha256 равен [32]byte, а не []byte, поэтому, когда новички пытаются записать его в файл, например:

sum := sha256.Sum256(data)
w.Write(sum)

, они получат ошибку.Правильный способ - использовать

w.Write(sum[:])

Однако что вы хотите?Просто доступ к строке байтово?Вы можете легко преобразовать string в []byte, используя:

bytes := []byte(str)

, но это не массив, а фрагмент.Также byte! = rune.Если вы хотите оперировать «персонажами», вам нужно использовать rune ... не byte.

0 голосов
/ 13 февраля 2016

Завершено создание специфичных для массива методов для этого. Очень похоже на пакет encoding / binary со специальными методами для каждого типа int. Например binary.BigEndian.PutUint16([]byte, uint16).

func byte16PutString(s string) [16]byte {
    var a [16]byte
    if len(s) > 16 {
        copy(a[:], s)
    } else {
        copy(a[16-len(s):], s)
    }
    return a
}

var b [16]byte
b = byte16PutString("abc")
fmt.Printf("%v\n", b)

Выход:

[0 0 0 0 0 0 0 0 0 0 0 0 0 97 98 99]

Обратите внимание, что я хотел заполнить слева, а не справа.

http://play.golang.org/p/7tNumnJaiN

0 голосов
/ 20 июля 2015

Помимо методов, упомянутых выше, вы также можете сделать трюк как

s := "hello"
b := *(*[]byte)(unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&s))))

Go Play: http://play.golang.org/p/xASsiSpQmC

Никогда не используйте это: -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...