Golang新手关于ioutil包使用的疑问

Golang新手关于ioutil包使用的疑问 pkg.go.dev/io/ioutil 上写着:“自 Go 1.16 起,相同的功能现在由 package iopackage os 提供,在新代码中应优先使用这些实现。”

这是否意味着:直接使用 ioos 包就足够了,并且比 ioutil 更好。所以不要使用 ioutil

如果是这样,为什么这个包没有从 Go 标准库中移除?我知道 Go 追求简洁。如果移除了不推荐的包,不是更好吗?

如果我错了,请见谅 🙂

注意:我是编程新手。谢谢。


更多关于Golang新手关于ioutil包使用的疑问的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

你好,对于任何编程语言来说,保留最古老的函数/库都是非常常见的做法,只要它不是一个确定的错误。这是因为如果将其移除,旧的代码就需要从头重写,可能会出现意想不到的不兼容问题,并且维护旧代码也会变得非常困难。

更多关于Golang新手关于ioutil包使用的疑问的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


如果是这样,为什么这个包没有被从 Go 标准库中移除?我知道 Go 追求简洁。如果移除了不推荐的包,不是更好吗?

因为 Go 承诺了对 Go 1 的向后兼容性 - Go 1 与 Go 程序的未来 - Go 编程语言

常见问题解答 (FAQ) - Go 编程语言中进一步阐明:

API 可能会增长,获得新的包和功能,但不会以破坏现有 Go 1 代码的方式进行。

通常来说,尽可能保持向后兼容性是一种行业惯例。

删除——严格来说,是一种单向操作,被删除的实体通常是不可恢复的,因此会在预期方面破坏用户体验。Go 在全球许多关键系统中使用,在没有仔细规划和沟通的情况下引入微小的破坏性变更都可能是灾难性的。

是的,你的理解完全正确。自 Go 1.16 起,ioutil 包已被弃用,其功能已分散到 ioos 包中。在新代码中,应优先使用 ioos 包中的对应函数。

ioutil 包没有被移除,主要是为了保持向后兼容性。Go 语言非常重视现有代码的稳定性,直接移除一个广泛使用的标准库包会导致大量旧代码无法编译。因此,Go 团队通常采用的方式是将其标记为弃用(在文档中明确说明),并引导开发者使用新的替代方案,而不是立即移除。

以下是 ioutil 中常见函数及其替代方案的示例:

1. 读取整个文件 之前使用 ioutil.ReadFile

data, err := ioutil.ReadFile("test.txt")

现在应使用 os.ReadFile

data, err := os.ReadFile("test.txt")

2. 写入整个文件 之前使用 ioutil.WriteFile

err := ioutil.WriteFile("test.txt", data, 0644)

现在应使用 os.WriteFile

err := os.WriteFile("test.txt", data, 0644)

3. 读取目录内容 之前使用 ioutil.ReadDir

files, err := ioutil.ReadDir(".")

现在应使用 os.ReadDir(注意:返回值为 []os.DirEntry):

entries, err := os.ReadDir(".")
for _, entry := range entries {
    info, _ := entry.Info()
    fmt.Println(info.Name())
}

4. 创建临时文件和目录 之前使用 ioutil.TempFileioutil.TempDir

f, err := ioutil.TempFile("", "example")
dir, err := ioutil.TempDir("", "example")

现在应使用 os.CreateTempos.MkdirTemp

f, err := os.CreateTemp("", "example")
dir, err := os.MkdirTemp("", "example")

5. 实现 io.Reader 的 Discard 之前使用 ioutil.Discard

io.Copy(ioutil.Discard, reader)

现在应使用 io.Discard

io.Copy(io.Discard, reader)

6. 实现 io.Reader 的 NopCloser 之前使用 ioutil.NopCloser

rc := ioutil.NopCloser(reader)

现在应使用 io.NopCloser

rc := io.NopCloser(reader)

因此,对于新项目,请直接使用 ioos 包中的这些函数,避免使用 ioutil。对于现有代码,可以在维护时逐步迁移到新的 API。

回到顶部