Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between the string and []byte in Go?

Tags:

string

slice

go

s := "some string"
b := []byte(s) // convert string -> []byte
s2 := string(b) // convert []byte -> string

what is the difference between the string and []byte in Go?

When to use "he" or "she"?

Why?

bb := []byte{'h','e','l','l','o',127}
ss := string(bb)
fmt.Println(ss)

hello

The output is just "hello", and lack of 127, sometimes I feel that it's weird.

like image 859
Jason Zhou Avatar asked Sep 17 '15 08:09

Jason Zhou


2 Answers

string and []byte are different types, but they can be converted to one another:

3 . Converting a slice of bytes to a string type yields a string whose successive bytes are the elements of the slice.

4 . Converting a value of a string type to a slice of bytes type yields a slice whose successive elements are the bytes of the string.

Blog: Arrays, slices (and strings): The mechanics of 'append':

Strings are actually very simple: they are just read-only slices of bytes with a bit of extra syntactic support from the language.

Also read: Strings, bytes, runes and characters in Go

When to use one over the other?

Depends on what you need. Strings are immutable, so they can be shared and you have guarantee they won't get modified.

Byte slices can be modified (meaning the content of the backing array).

Also if you need to frequently convert a string to a []byte (e.g. because you need to write it into an io.Writer()), you should consider storing it as a []byte in the first place.

Also note that you can have string constants but there are no slice constants. This may be a small optimization. Also note that:

The expression len(s) is constant if s is a string constant.

Also if you are using code already written (either standard library, 3rd party packages or your own), in most of the cases it is given what parameters and values you have to pass or are returned. E.g. if you read data from an io.Reader, you need to have a []byte which you have to pass to receive the read bytes, you can't use a string for that.


This example:

bb := []byte{'h','e','l','l','o',127}

What happens here is that you used a composite literal (slice literal) to create and initialize a new slice of type []byte (using Short variable declaration). You specified constants to list the initial elements of the slice. You also used a byte value 127 which - depending on the platform / console - may or may not have a visual representation.

like image 162
icza Avatar answered Sep 28 '22 04:09

icza


Late but i hope this could help.

In simple words

  • Bit: 0 and 1 is how machines represents all the information
  • Byte: 8 bits that represents UTF-8 encodings i.e. characters
  • [ ]type: slice of a given data type. Slices are dynamic size arrays.
  • [ ]byte: this is a byte slice i.e. a dynamic size array that contains bytes i.e. each element is a UTF-8 character.
  • String: read-only slices of bytes i.e. immutable

With all this in mind:

s := "Go"
bs := []byte(s)
fmt.Printf("%s", bs)     // Output: Go
fmt.Printf("%d", bs)     // Output: [71 111]

or

bs := []byte{71, 111}
fmt.Printf("%s", bs)     // Output: Go

%s converts byte slice to string

%d gets UTF-8 decimal value of bytes


IMPORTANT:

As strings are immutable, they cannot be changed within memory, each time you add or remove something from a string, GO creates a new string in memory. On the other hand, byte slices are mutable so when you update a byte slice you are not recreating new stuffs in memory.

So choosing the right structure could make a difference in your app performance.

like image 33
Juan-Kabbali Avatar answered Sep 28 '22 03:09

Juan-Kabbali