[]byte and string convert?

630 views
Skip to first unread message

xie cui

unread,
Jan 29, 2021, 7:51:57 AM1/29/21
to golang-nuts
does convert string to []byte, and convert []byte to string alway alloc new space, and the new space is in heap? 
if it is not, please show some demo codes?

xie cui

unread,
Jan 29, 2021, 7:55:07 AM1/29/21
to golang-nuts
I mean convert using 
s := "abcefg"
b := []byte(s)
s2 := string(b)

not convert using some unsafe.Pointer trick.

Amnon

unread,
Jan 29, 2021, 9:34:44 AM1/29/21
to golang-nuts
Generally yes.
As strings are immutable, and []byte is not, 
if you convert from string -> []byte, you need a new copy which can be written without changing the original string (which may be referred to elsewhere).

If you convert from []byte -> string, then you need a new copy so that any later changes to the byte slice won't change the contents of the string.

There are a few specialised situations (like conversion from []byte -> string inside a map index where these copies optimised away.
But otherwise you are stuck with an allocation.

The fastest way to convert between string and []byte is not to convert between string and []byte, (i.e. just use []byte everywhere).

Axel Wagner

unread,
Jan 29, 2021, 9:35:05 AM1/29/21
to xie cui, golang-nuts
Hi,

neither is *always* the case. One example of where no allocation is done is when converting a []byte into a string to use as a map-index, as long as a) it is done in one expression and b) the key doesn't have to be stored (i.e. the access is read-only):

b := []byte{70,111,111}
m := make(map[string]int)
v := m[string(b)] // does not allocate

And as always, a conversion might end on the stack, if the compiler can prove that the storage doesn't have to survive the call, e.g.

 x := "Hello world"
os.Stdout.Write([]byte(x)) // does not escape

(note, that in this example, it's important that `os.Stdout` is an `*os.File`, not just an `io.Writer`, so the compiler actually knows the real function that is called).

But, in general, I think you can assume that such a conversion has to allocate and I'd guess that in most cases, it needs to go on the heap. You can use `-gcflags=-m` to see if a particular conversion allocates or not.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/18219e42-1a46-42ba-a28b-2b432ccc0a40n%40googlegroups.com.

Robert Engels

unread,
Jan 29, 2021, 9:51:16 AM1/29/21
to Amnon, golang-nuts
And if you use byte[] everywhere rather than string be prepared for lots of panics and hard to detect bugs. :)

On Jan 29, 2021, at 8:35 AM, Amnon <amn...@gmail.com> wrote:

Generally yes.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages