使用json.Marshal转[]byte后,fmt.Println与os.Stdout.Write输出差异原因?
为什么fmt.Println和os.Stdout.Write处理[]byte的结果不一样?
咱们先看你的代码和输出,核心原因是这两个函数对[]byte的处理逻辑完全不同:
首先是你给出的代码示例:
package main import ( "encoding/json" "fmt" "os" ) func main(){ str := "My string" dat,_:= json.Marshal(str) fmt.Println(dat) os.Stdout.Write(dat) }
对应的输出结果是:
[34 77 121 32 115 116 114 105 110 103 34] "My string"
先聊聊fmt.Println的处理逻辑
fmt.Println会根据参数的类型来决定输出格式:
- 当参数是
[]byte时,它会把这个切片当成一组字节数值来处理(毕竟byte本质是uint8的别名),所以会遍历切片里的每个元素,打印它们的十进制数值,最后用方括号包裹起来。 - 你这里
json.Marshal(str)得到的dat,是字符串"My string"的JSON序列化结果,对应的字节序列就是[34, 77, 121, 32, 115, 116, 114, 105, 110, 103, 34](34是双引号的ASCII码,77是'M',以此类推),所以fmt.Println(dat)直接输出了这些字节的数值。
再看os.Stdout.Write的逻辑
os.Stdout实现了io.Writer接口,它的Write方法的作用是把传入的[]byte作为原始字节流直接写入标准输出:
- 系统会按照默认字符编码(一般是UTF-8)把这些字节解析成对应的字符,所以当你传入
dat时,这些字节对应的就是带双引号的字符串"My string",自然就直接输出这个字符串了。
小技巧:让fmt.Println也输出字符串的方法
只要把[]byte转换成string类型就行,修改成下面这样:
fmt.Println(string(dat))
这样输出就会和os.Stdout.Write(dat)的结果完全一致了。
内容的提问来源于stack exchange,提问作者Ibnjunaid
相关产品推荐
相关产品推荐

