scala - "using/try-with-resources"的简单 Scala 模式(自动资源管理)

标签 scala resource-management

C# 有 usingIDisposable界面。 Java 7+ 具有与 try 相同的功能和 AutoCloseable界面。 Scala 允许您选择自己的实现来解决这个问题。

scala-arm 似乎是流行的选择,由 Typesafe 的一名员工维护。但是,对于这样一个简单的行为,它似乎非常复杂。澄清一下,使用说明很简单,但了解所有代码在内部是如何工作的却相当复杂。

我刚刚写了以下 super 简单的ARM解决方案:

object SimpleARM {
  def apply[T, Q](c: T {def close(): Unit})(f: (T) => Q): Q = {
    try {
      f(c)
    } finally {
      c.close()
    }
  }
}
  • 像简单 ARM 这样的东西有什么好处吗?似乎所有额外的复杂性都应该带来额外的好处。
  • 通常,最好使用其他人支持的公共(public)开源库来实现通用行为,而不是使用自定义代码。
  • 任何人都可以推荐任何改进吗?
  • 这种简单的方法有什么限制吗?
  • 最佳答案

    这里是我较新的简单、一目了然的Scala ARM。这完全支持我能想到的每个用例,包括多个资源和 yield 值。这使用了一个非常简单的理解用法语法:

    class AutoCloseableWrapper[A <: AutoCloseable](protected val c: A) {
      def map[B](f: (A) => B): B = {
        try {
          f(c)
        } finally {
          c.close()
        }
      }
    
      def foreach(f: (A) => Unit): Unit = map(f)
    
      // Not a proper flatMap.
      def flatMap[B](f: (A) => B): B = map(f)
    
      // Hack :)    
      def withFilter(f: (A) => Boolean) = this
    }
    
    object Arm {
      def apply[A <: AutoCloseable](c: A) = new AutoCloseableWrapper(c)
    }
    

    这是演示使用:
    class DemoCloseable(val s: String) extends AutoCloseable {
      var closed = false
      println(s"DemoCloseable create ${s}")
    
      override def close(): Unit = {
        println(s"DemoCloseable close ${s} previously closed=${closed}")
        closed = true
      }
    }
    
    object DemoCloseable {
      def unapply(dc: DemoCloseable): Option[(String)] = Some(dc.s)
    }
    
    object Demo {
      def main(args: Array[String]): Unit = {
        for (v <- Arm(new DemoCloseable("abc"))) {
          println(s"Using closeable ${v.s}")
        }
    
        for (a <- Arm(new DemoCloseable("a123"));
             b <- Arm(new DemoCloseable("b123"));
             c <- Arm(new DemoCloseable("c123"))) {
          println(s"Using multiple resources for comprehension. a.s=${a.s}. b.s=${b.s}. c.s=${c.s}")
        }
    
        val yieldInt = for (v <- Arm(new DemoCloseable("abc"))) yield 123
        println(s"yieldInt = $yieldInt")
    
        val yieldString = for (DemoCloseable(s) <- Arm(new DemoCloseable("abc")); c <- s) yield c
        println(s"yieldString = $yieldString")
    
        println("done")
      }
    }
    

    关于scala - "using/try-with-resources"的简单 Scala 模式(自动资源管理),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25634455/

    相关文章:

    c# - "opening a connection"实际上是什么意思?

    scala - ETL Scala 脚本出现异常

    scala - 我可以将这个异步Java网络API转换成Monadic表示形式(或其他惯用的表示形式)吗?

    Scala 的位置方差

    Azure 资源管理器 SQL 数据库模板

    google-app-engine - 是否可以防止 Google App Engine 上的 DoSing?

    c++ - 通用句柄类

    c++ - 5 法则(对于构造函数和析构函数)是否过时了?

    java - 将 Spark "Library"添加到 Scala 项目

    scala - 在 Slick 3.0.0-RC3 中更新行,使用