Go's ioutil package to be deprecated in 1.16
Oliver Lowe
It was easy to see the motivation for the deprecation in Go tech lead Russ Cox’s proposal:
io/ioutil, like most things with util in the name, has turned out to be a poorly defined and hard to understand collection of things.
In a series of a few changes, the entire ioutil
package is due to become deprecated
starting from Go 1.16.
Existing code using ioutil
will continue to work;
ioutil
will consist of simple wrappers to new functions which reside in the io
and os
packages.
Initially, a proposal by Cox back in July was approved which saw the move of
general I/O helpers, like ioutil.ReadAll
,
out of package ioutil
and into io
.
Remaining code in ioutil
consisted of OS file system helpers, like ReadFile
.
A few months later, a second proposal by Cox suggested moving those into package os
.
Acceptance of the proposal was the nail in ioutil
’s coffin.
The deprecation of ioutil
comes as part of what will be a significant Go release.
Module-aware mode is enabled by default.
The darwin/arm64
port will be released which means Go will be natively supported on Apple’s new Macs using their M1 SoC.
A new io/fs
package, demoed last year, will make its debut.
Whilst new features tend to get more journalistic coverage, long time Go programmers may be encouraged by this recent deprecation. Relatively thankless work such as this suggests a dedication to keeping the core of the language clean and easy to understand; values that brought so many programmers to the language in the first place.
Example Migration
Migration of code using ioutil
should be straightforward.
Here is an example migration adapted from package wal
in the popular Prometheus project:
package wal
import (
"fmt"
"io/ioutil"
"os"
...
)
func TestLastCheckpoint(t *testing.T) {
dir, err := ioutil.TempDir("", "test_checkpoint")
require.NoError(t, err)
defer func() {
require.NoError(t, os.RemoveAll(dir))
}()
...
We rename ioutil.TempDir
to os.MkDirTemp
.
Now that ioutil
is no longer needed, and os
was already imported,
we have one less dependency:
package wal
import (
"fmt"
"os"
...
)
func TestLastCheckpoint(t *testing.T) {
dir, err := os.MkDirTemp("", "test_checkpoint")
require.NoError(t, err)
defer func() {
require.NoError(t, os.RemoveAll(dir))
}()
...
Member of the Go team Bryan Mills has an open proposal for the go fix
command to automatically migrate deprecated code.
This means existing code using ioutil
may not have to be changed by hand.
Discussion of the proposal stalled over a year ago.
Additional feedback from the proposal review committee may be requested later this year.