“使用/尝试资源"的简单 Scala 模式;(自动资源管理) [英] Simple Scala pattern for "using/try-with-resources" (Automatic Resource Management)
问题描述
C# 具有 using
和 IDisposable
接口.Java 7+ 具有与 try
和 AutoCloseable
接口相同的功能.Scala 允许您针对此问题选择自己的实现方式.
C# has using
with the IDisposable
interface. Java 7+ has identical functionality with try
and the AutoCloseable
interface. Scala lets you choose your own implementation to this issue.
scala-arm 似乎是流行的选择,由 Typesafe 的一名员工维护.然而,对于这样一个简单的行为来说,似乎非常复杂.澄清一下,使用说明很简单,但了解所有代码在内部是如何工作的却相当复杂.
scala-arm seems to be the popular choice, and is maintained by one of the Typesafe employees. However, it seems very complicated for such a simple behavior. To clarify, the usage instructions are simple, but understanding how all that code is working internally is rather complex.
我刚刚写了以下超级简单的ARM解决方案:
I just wrote the following super simple ARM solution:
object SimpleARM {
def apply[T, Q](c: T {def close(): Unit})(f: (T) => Q): Q = {
try {
f(c)
} finally {
c.close()
}
}
}
- 像 simple-arm 这样的东西有什么好处吗?似乎所有额外的复杂性都应该带来额外的好处.
- 通常情况下,与使用自定义代码相比,最好使用其他人支持的公共开源库来实现通用行为.
- 有人可以推荐任何改进吗?
- 这种简单的方法有什么限制吗?
推荐答案
这里是我更新的简单,一看就懂,Scala ARM.这完全支持我能想到的每个用例,包括多个资源和产量值.这使用了一个非常简单的理解用法语法:
Here is my newer simple, understand at a glance, Scala ARM. This fully supports every use case I can think of including multiple resources and yield values. This uses a very simple for comprehension usage syntax:
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 模式;(自动资源管理)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!