Reputation: 512
I had this code where I convert a string into a []byte
slice using json.Marshal
. When printing, why does fmt.Println()
write numbers to stdout while os.Stdout.Write
writes the string.
My question is how does fmt.Println
parse the []byte
.
package main
import (
"encoding/json"
"fmt"
"os"
)
func main(){
str := "My string"
dat,_:= json.Marshal(str)
fmt.Println(dat)
os.Stdout.Write(dat)
}
I get the following Output
[34 77 121 32 115 116 114 105 110 103 34]
"My string"
Upvotes: 0
Views: 8000
Reputation: 21045
fmt.Println
generates the friendly format for a byte slice. Because byte slices can contain anything at all (and not just printable characters), it shows you the individual byte values. Per the docs: a byte slice is printed out as:
the uninterpreted bytes of the string or slice
On the other hand, os.Stdout.Write
writes the byte slice to standard out. Because they are printable characters, your terminal renders them properly.
Try it with non-printable characters, and the reason for fmt.Println
's behavior will become clear:
func main() {
dat := []byte{0, 1, 2, 3, 4}
fmt.Println(dat)
os.Stdout.Write(dat)
}
Outputs:
[0 1 2 3 4]
XXXX // four non-printable character placeholders (based on your terminal)
As for json, its output is a byte slice since this is the most useful format to be passed to a writer (network, disk, storage, etc...).
Upvotes: 7