I want to assign string to bytes array:
var arr [20]byte
str := "abc"
for k, v := range []byte(str) {
arr[k] = byte(v)
}
Have another method?
str
is greater than the length of arr
then you will get an "index out of range" error.
[]byte(“abc”)
to set a string to a bytes slice. See stackoverflow.com/a/62740786/12817546.string(b)
or a fmt.Sprintf("%s", b)
to set a bytes slice to a sting. See stackoverflow.com/a/62725637/12817546.
Safe and simple:
[]byte("Here is a string....")
For converting from a string to a byte slice, string -> []byte
:
[]byte(str)
For converting an array to a slice, [20]byte -> []byte
:
arr[:]
For copying a string to an array, string -> [20]byte
:
copy(arr[:], str)
Same as above, but explicitly converting the string to a slice first:
copy(arr[:], []byte(str))
The built-in copy function only copies to a slice, from a slice.
Arrays are "the underlying data", while slices are "a viewport into underlying data".
Using [:] makes an array qualify as a slice.
A string does not qualify as a slice that can be copied to, but it qualifies as a slice that can be copied from (strings are immutable).
If the string is too long, copy will only copy the part of the string that fits (and multi-byte runes may then be copied only partly, which will corrupt the last rune of the resulting string).
This code:
var arr [20]byte
copy(arr[:], "abc")
fmt.Printf("array: %v (%T)\n", arr, arr)
...gives the following output:
array: [97 98 99 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] ([20]uint8)
I also made it available at the Go Playground
b[i] = []byte("A")[0]
works, but b[i] = 'A'
ends up being much cleaner.
b[1] = '本'
[]byte(str)
creates new underlying array with make()
or not ? Or is it just returning a pointer copy to the original string.
[]byte(str)
calls the runtime.stringtoslicebyte
function. stringtoslicebyte
will allocate memory if needed and then call copy
. See: string.go. The copy
function copies bytes in a loop.
For example,
package main
import "fmt"
func main() {
s := "abc"
var a [20]byte
copy(a[:], s)
fmt.Println("s:", []byte(s), "a:", a)
}
Output:
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
, The `copy function is not dumb. Appending to and copying slices: "The number of elements copied is the minimum of len(src) and len(dst)."
Piece of cake:
arr := []byte("That's all folks!!")
[]byte
is preferred over arrays [20]byte
. Answer is correct based on best practices; if specifications or code necessitates arrays, then use copy
instead (see examples elsewhere in this thread).
I think it's better..
package main
import "fmt"
func main() {
str := "abc"
mySlice := []byte(str)
fmt.Printf("%v -> '%s'",mySlice,mySlice )
}
Check here: http://play.golang.org/p/vpnAWHZZk7
Go, convert a string to a bytes slice
You need a fast way to convert a []string to []byte type. To use in situations such as storing text data into a random access file or other type of data manipulation that requires the input data to be in []byte type.
package main
func main() {
var s string
//...
b := []byte(s)
//...
}
which is useful when using ioutil.WriteFile, which accepts a bytes slice as its data parameter:
WriteFile func(filename string, data []byte, perm os.FileMode) error
Another example
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)))
}
Output:
[104 101 108 108 111 32 119 111 114 108 100] hello world
Please check the link playground
Ended up creating array specific methods to do this. Much like the encoding/binary package with specific methods for each int type. For example 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)
Output:
[0 0 0 0 0 0 0 0 0 0 0 0 0 97 98 99]
Notice how I wanted padding on the left, not the right.
http://play.golang.org/p/7tNumnJaiN
byte16PutString
is a sort-of reimplementation of the builtin copy
function, that only supports creating new arrays instead of using an existing one. copy
has special compiler support, so it can handle different types of arguments, and it probably has a really high-performance implementation under the covers. Also, the OP's question asked about writing a string to an existing array, rather than allocating a new one, though most of the other answers seem to be ignoring that too...
Arrays are values... slices are more like pointers. That is [n]type
is not compatible with []type
as they are fundamentally two different things. You can get a slice that points to an array by using arr[:]
which returns a slice that has arr
as it's backing storage.
One way to convert a slice of for example []byte
to [20]byte
is to actually allocate a [20]byte
which you can do by using var [20]byte
(as it's a value... no make
needed) and then copy data into it:
buf := make([]byte, 10)
var arr [10]byte
copy(arr[:], buf)
Essentially what a lot of other answers get wrong is that []type
is NOT an array.
[n]T
and []T
are completely different things!
When using reflect []T
is not of kind Array but of kind Slice and [n]T
is of kind Array.
You also can't use map[[]byte]T
but you can use map[[n]byte]T
.
This can sometimes be cumbersome because a lot of functions operate for example on []byte
whereas some functions return [n]byte
(most notably the hash functions in crypto/*
). A sha256 hash for example is [32]byte
and not []byte
so when beginners try to write it to a file for example:
sum := sha256.Sum256(data)
w.Write(sum)
they will get an error. The correct way of is to use
w.Write(sum[:])
However, what is it that you want? Just accessing the string bytewise? You can easily convert a string
to []byte
using:
bytes := []byte(str)
but this isn't an array, it's a slice. Also, byte
!= rune
. In case you want to operate on "characters" you need to use rune
... not byte
.
Besides the methods mentioned above, you can also do a trick as
s := "hello"
b := *(*[]byte)(unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&s))))
Go Play: http://play.golang.org/p/xASsiSpQmC
You should never use this :-)
[]byte
object using your "conversion" – it fails badly when you try to amend p
, see: play.golang.org/p/WHGl756ucj. In your case, not sure why you would prefer double-unsafe over the b := []byte(s)
method.
cap()
of arbitrary size, which means it's reading into unknown memory. For this to be right, I think you'd need to make sure you allocate the full reflect.SliceHeader
size and manually set the cap
. Something like this: play.golang.org/p/fBK4dZM-qD
Success story sharing
[]byte
and not a set array of bytes[20]byte
when converting a string to bytes... Don't believe me? Check out Rob Pike's answer on this thread[]byte("one", "two")
?