为什么我从io.PipeReader中获取EOF?

时间:2017-10-13 18:41:22

标签: go

我在项目中使用类似的东西而且我有点困惑:为什么没有任何东西被打印出来?

package main
import (
    "fmt"
    "encoding/json"
    "io"
)

func main() {
    m := make(map[string]string)
    m["foo"] = "bar"

    pr, pw := io.Pipe()
    go func() { pw.CloseWithError(json.NewEncoder(pw).Encode(&m)) }()

    fmt.Fscan(pr)
}

https://play.golang.org/p/OJT1ZRAnut

这是某种竞争条件吗?我尝试删除pw.CloseWithError但它没有任何改变。

1 个答案:

答案 0 :(得分:5)

fmt.Fscan有两个参数。读取的读取器,以及要填充的对象的一个​​或多个指针。其结果为(n int, err error),其中n是读取的项目数,errn小于(variadic ...)数据切片的原因你输入第二个参数的对象。

在这种情况下,数据对象的切片长度为零,因此Fscan填充零对象并且不读取任何数据。它尽职尽责地报告它扫描了0个对象,并且由于该数字不小于您传入其中的对象数量,因此报告nil错误。

尝试以下方法:

func main() {
    m := make(map[string]string)
    m["foo"] = "bar"

    pr, pw := io.Pipe()
    go func() { pw.CloseWithError(json.NewEncoder(pw).Encode(&m)) }()

    var s string
    n, err := fmt.Fscan(pr, &s)
    fmt.Println(n, err)  // should be 1 <nil>
    fmt.Println(s)       // should be {"foo":"bar"}
}