Відповіді:
Безпечний і простий:
[]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
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Функція `копіювання не є німою. Додавання та копіювання фрагментів : "Кількість скопійованих елементів - мінімум 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))))
Перейти: 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то ви отримаєте помилку "індекс поза діапазоном".