Could someone please explain (or/and share examples) when and why readers should to be closed explicitly, i.e. implement io.ReadCloser, not just io.Reader.
-
2Any time you need to close your reader. – Jonathan Hall Oct 02 '20 at 07:02
2 Answers
For example, when you are working with files, or any resource that should be closed to release the allocated resource (or memory for example for your resource, e.g. C
code calling from Go
).
You may use it when you have Read
and Close
methods, an example to show that you may use one common function to work with different types using io.ReadCloser
:
package main
import (
"fmt"
"io"
"log"
"os"
)
func main() {
f, err := os.Open("./main.go")
if err != nil {
log.Fatal(err)
}
doIt(f)
doIt(os.Stdin)
}
func doIt(rc io.ReadCloser) {
defer rc.Close()
buf := make([]byte, 4)
n, err := rc.Read(buf)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", buf[:n])
}
Run and enter 12345
as an input, Output:
pack
12345
1234
See also:
Does Go automatically close resources if not explicitly closed?

- 14,541
- 6
- 42
- 58
It's for an explicit definition of Reader and Closer interface. So let's say you write some functionality that reads data, but you also want to close resource after doing it (again not to leak descriptors).
func ...(r io.ReaderCloser) {
defer r.Close()
... // some reading
}
anything you pass in it will need to have both interfaces defined, is it os.File or any custom struct, in this case, you are forcing client of your API to define Read
and Close
interfaces implementations, not just io.Reader.

- 4,795
- 2
- 24
- 33