Ответы:
Безопасно и просто:
[]byte("Here is a string....")
[]byte("one", "two")
?
Для преобразования строки в фрагмент байта 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
b[i] = []byte("A")[0]
работает, но в b[i] = 'A'
итоге получается намного чище.
b[1] = '本'
Например,
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]
s
, функция `copy не глупа. Добавление и копирование фрагментов : «Количество скопированных элементов - это минимум len (src) и len (dst)».
Кусок пирога:
arr := []byte("That's all folks!!")
[]byte
предпочтительнее массивов [20]byte
. Ответ правильный на основе лучших практик; если для спецификаций или кода требуются массивы, используйте copy
вместо этого (см. примеры в другом месте в этой теме).
Я думаю, что это лучше ..
package main
import "fmt"
func main() {
str := "abc"
mySlice := []byte(str)
fmt.Printf("%v -> '%s'",mySlice,mySlice )
}
Проверьте здесь: http://play.golang.org/p/vpnAWHZZk7
Вам нужен быстрый способ преобразования строки [] в тип байта []. Для использования в ситуациях, таких как сохранение текстовых данных в файле произвольного доступа или другого типа манипулирования данными, который требует, чтобы входные данные имели тип байта [].
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 119 111 114 108 100] привет мир
Пожалуйста, проверьте ссылку игровая площадка
Закончилось создание специальных методов для этого. Очень похоже на кодировку / двоичный пакет с конкретными методами для каждого типа 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]
Обратите внимание, как я хотел заполнить слева, а не справа.
byte16PutString
- это своего рода переопределение встроенной copy
функции, которая поддерживает создание только новых массивов, а не использование существующих. copy
имеет специальную поддержку компилятора, поэтому он может обрабатывать различные типы аргументов и, вероятно, имеет действительно высокопроизводительную реализацию под прикрытием. Кроме того, вопрос ОП задал вопрос о записи строки в существующий массив, а не о выделении нового, хотя большинство других ответов, похоже, тоже игнорируют это ...
answer
- это правильно, все здесь, чтобы учиться и ободрять других
Помимо методов, упомянутых выше, вы также можете сделать трюк, как
s := "hello"
b := *(*[]byte)(unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&s))))
Go Play: http://play.golang.org/p/xASsiSpQmC
Вы никогда не должны использовать это :-)
[]byte
нужный объект, используя свое «преобразование» - он плохо работает, когда вы пытаетесь внести изменения p
, см .: play.golang.org/p/WHGl756ucj . В вашем случае не уверен, почему вы предпочитаете двойной небезопасный b := []byte(s)
метод.
cap()
произвольный размер, что означает, что он читает в неизвестную память. Чтобы это было правильно, я думаю, вам нужно убедиться, что вы выделите полный reflect.SliceHeader
размер и вручную установите cap
. Примерно так: play.golang.org/p/fBK4dZM-qD
Массивы - это значения ... срезы больше похожи на указатели. Это [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
имеет вид Array.
Вы также не можете использовать, 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
.
str
больше, чем длина,arr
вы получите ошибку «индекс вне диапазона».