47281
io.Reader インタフェースの

```

    func Read(p []byte) (n int, err error)
    
```

で、全てを読みつくしたかどうかを判定する方法で迷っています。  
思いつく限りでは以下の３つなのですが、優劣はありますでしょうか。

**１．戻り値`n` がゼロだったら「終わり」**

```

    package main
    
    import (
        "bytes"
        "fmt"
    )
    
    func main() {
    
        r := bytes.NewBuffer([]byte{1, 2, 3})
        b := make([]byte, 2)
    
        for {
            n, err := r.Read(b)
    
            if n == 0 {
                break
            }
    
            if err != nil {
                panic(err)
            }
    
            fmt.Println(b[:n])
        }
    }
    
```

**Ｂ．戻り値`err` が `io.EOF` だったら「終わり」**

```

        for {
            n, err := r.Read(b)
    
            if err != nil {
                if err == io.EOF {
                    break
                }
                panic(err)
            }
    
            fmt.Println(b[:n])
        }
    
```

**Ｃ．戻り値`n` が 用意したバッファサイズより小さかったら「終わり」**

```

        for {
            n, err := r.Read(b)
    
            if err != nil {
                panic(err)
            }
    
            fmt.Println(b[:n])
    
            if n < len(b) {
                break
            }
        }
    
```
CC BY-SA 4.0
2018-08-06T04:17:42.297
47272
2018-08-06T10:24:23.783
19759
question
go
io.Reader の終端判定方法
[`io.Reader`のドキュメント](https://golang.org/pkg/io/#Reader)には、

> It returns the number of bytes read (0 <= n <= len(p)) and any error
> encountered.

とあるので、`n==0`だけで判定すると誤りと思います。  
また、上記説明の後に、

> If some data is available but not len(p) bytes, Read conventionally returns
> what is available instead of waiting for more.

ともあるので、`n < len(p)`で判定するのも誤りと思います。

なので、質問文にある「B. 戻り値`err`が`io.EOF`だったら『終わり』」と判定するのが  
正しいかと思います。

＃ただし、`err`が`io.EOF`でも、`n>0`の場合があると記載されているので、`n==0`との複合条件で判断した方がよいと思います。
CC BY-SA 4.0
2018-08-06T10:24:23.783
47281
2018-08-06T10:24:23.783
20098
47272
answer