io.Pipe读写不匹配:写入97为何读出[57,55]?
为什么Go代码中字符'a'写入管道后读出的是[57 55]?
先看你给出的代码:
package main import ( "bytes" "fmt" "io" ) func main() { r, w := io.Pipe() go func() { defer w.Close() in := 'a' // 单引号 fmt.Println("writing: ", in) fmt.Fprint(w, in) }() defer r.Close() buf := new(bytes.Buffer) buf.ReadFrom(r) fmt.Print("read: ", buf.Bytes()) }
运行后输出:
writing: 97 read: [57 55]
核心原因:fmt.Fprint的类型处理逻辑
这个问题其实是踩了Go里fmt包和类型转换的小坑,我给你掰扯清楚:
- Go里单引号包裹的
'a'是rune类型,它的底层数值就是ASCII码97,所以fmt.Println("writing: ", in)会直接输出这个数值97。 fmt.Fprint函数的行为很关键:如果传入的参数不是字符串或字节序列,它会把参数转换成人类可读的字符串形式,而不是直接写入原始的二进制值。
所以当你调用fmt.Fprint(w, in)时,in是rune类型的97,fmt包会把这个数值转换成字符串"97",然后把这个字符串的两个字节写入管道:
- '9'的ASCII码是57
- '7'的ASCII码是55
这就是你读出[57 55]的原因——你读到的是字符串"97"的字节,而不是字符'a'的字节97,这就是97和[57,55]的关联点。
为什么两种修改方式能得到预期结果?
- 当把
in定义为"a"时,它本身就是string类型,fmt.Fprint会直接写入这个字符串的原始字节,也就是[97]。 - 当使用
fmt.Fprint(w, string(in))时,你主动把rune类型的97转换成了对应的字符字符串"a",fmt.Fprint写入的自然就是这个字符串的字节[97]了。
内容的提问来源于stack exchange,提问作者hol
相关产品推荐
相关产品推荐

