Example: io.NopCloser
io.NopCloser adapts an io.Reader to an io.ReadCloser by adding a Close method that does nothing.
It is useful when an API requires an io.ReadCloser, but the underlying reader has no resource that needs closing.
The important rule is:
io.NopCloseradapts an interface. It does not manage the underlying resource.
Quick Example
Output:
rc.Read forwards to src.Read.
rc.Close() simply returns nil.
No data is copied or buffered by NopCloser.
Why It Exists
Some APIs require an io.ReadCloser even when the underlying data is just an in-memory reader.
For example, http.Response.Body is an io.ReadCloser:
This is common when constructing HTTP responses for tests, mocks, or custom proxy code.
For http.Request, io.NopCloser is usually unnecessary. http.NewRequest accepts an io.Reader and handles common in-memory reader types itself.
Close Does Nothing
Closing the wrapper does not close the underlying reader.
The underlying reader is still usable.
This is intentional: NopCloser has no ownership of the resource represented by the reader.
The Important Trap
Do not use io.NopCloser to hide a resource that actually needs cleanup.
For example:
rc.Close() only calls the no-op Close provided by NopCloser.
The file descriptor remains open unless file.Close() is called separately.
Use the original io.ReadCloser when the underlying resource needs lifecycle management:
The same principle applies to network connections, response bodies, and other resource-owning readers.
Common Use
Use io.NopCloser when:
- an in-memory reader must satisfy
io.ReadCloser - constructing an
http.Responsefor a test - replacing a request or response body with in-memory data
- an API requires
io.ReadCloser, but there is no resource to close
Do not use it when:
- the underlying object owns a file descriptor
- the underlying object owns a network connection
Closehas meaningful cleanup semantics- the value already implements
io.ReadCloser
Rule of Thumb
Use
io.NopCloserto add a no-opClose, not to suppress a realClose.
It changes the interface presented to the caller, not the ownership or lifetime of the underlying resource.