1. 概述

在 Java 中,我们可以使用 try-with-resources 语句来自动关闭代码中用到的资源。该语法适用于所有实现了 AutoCloseable 接口的类。

遗憾的是,Scala 并没有直接提供类似的语法支持。本文将介绍两种在 Scala 中实现类似功能的方法。

2. Java 中的 Try-With-Resources

当我们编写一个需要读取文件内容的 Java 程序时,通常会创建一个持有文件句柄的对象(如 BufferedReader)。

当不再需要这个资源时,我们必须手动释放它:

try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
    return reader.readLine();
}

这段代码等价于我们手动写 finally 块去关闭资源:

BufferedReader reader = new BufferedReader(new FileReader(filePath));
try {
    return reader.readLine();
} finally {
    if (reader != null) {
        reader.close();
   } 
}

✅ 使用 try-with-resources 可以避免忘记关闭资源的问题,也减少了样板代码。

3. Scala 中的 Using 和 Using.Manager

从 Scala 2.13 开始,标准库引入了 scala.util.Using 工具类,用于简化资源管理逻辑。

3.1 单个资源的自动管理

首先导入相关包:

import scala.util.Using

然后像这样使用:

Using(new BufferedReader(new FileReader(filePath))) { reader =>
  reader.readLine()
}

这段代码会在作用域结束时自动调用 reader.close(),即使发生异常也会确保资源被释放。

3.2 多个资源的自动管理

如果我们有多个资源要管理,可以使用 Using.Manager

Using.Manager { use =>
  val reader = use(new BufferedReader(new FileReader(filePath)))
  val anotherReader = use(new BufferedReader(new FileReader(otherFilePath)))

  reader.readLine()
  anotherReader.readLine()
}

⚠️ 注意:这里的 use 是一个函数,用来标记哪些资源需要被自动关闭。

4. 小结

虽然 Scala 没有原生的 try-with-resources 语法,但从 2.13 版本开始,通过 UsingUsing.Manager 我们也能优雅地实现相同的效果。

对于日常开发来说,这两个工具已经足够应付绝大多数资源管理场景,而且写法更简洁、更符合函数式风格。


原始标题:Try-With-Resources in Scala