-
Notifications
You must be signed in to change notification settings - Fork 18.6k
Description
The documented behavior of io.Closer is:
The behavior of Close after the first call is undefined. Specific implementations may document their own behavior.
The fact that the behavior of a second call to Close is undefined means that an implementation may actually panic. Unfortunately, too many callers of Close make the assumption that the call is safe to make twice. For example:
f, ... := foo.Open(...)
defer f.Close() // panic!
...
if err := f.Close(); err != nil {
...
}The documentation regarding undefined behavior was made 5 years ago by @bradfitz because he observed people making this assumption. However, time has demonstrated that people still widely assume Close to be idempotent.
Thus, I propose changing the documentation to match what people expect:
Calling Close is an idempotent operation that returns the same error value for all subsequent calls as the first call.
This may need to be a Go2 change, but it may be worth considering today given how pervasive the assumption already is.