Scala 是否有与 golangs defer 相同的功能?
来自: http: //golang.org/doc/effective_go.html#defer
Go 的 defer 语句安排一个函数调用(延迟函数)在执行 defer 的函数返回之前立即运行。这是一种不寻常但有效的方式来处理诸如无论函数采用哪条路径返回都必须释放资源的情况。典型示例是解锁互斥锁或关闭文件。
Scala 是否有与 golangs defer 相同的功能?
来自: http: //golang.org/doc/effective_go.html#defer
Go 的 defer 语句安排一个函数调用(延迟函数)在执行 defer 的函数返回之前立即运行。这是一种不寻常但有效的方式来处理诸如无论函数采用哪条路径返回都必须释放资源的情况。典型示例是解锁互斥锁或关闭文件。
Scala 并非defer
按设计提供,但是您可以通过将函数包装在另一个函数中来自己创建它,并传递一个跟踪要调用的函数的对象。
例子:
class DeferTracker() {
class LazyVal[A](val value:() => A)
private var l = List[LazyVal[Any]]()
def apply(f: => Any) = { l = new LazyVal(() => f) :: l }
def makeCalls() = l.foreach { x => x.value() }
}
def Deferrable[A](context: DeferTracker => A) = {
val dt = new DeferTracker()
val res = context(dt)
dt.makeCalls
res
}
在此示例中,Deferable
将是调用context
并返回其内容的包装函数,为它提供一个跟踪defer
调用的对象。
您可以像这样使用此构造:
def dtest(x:Int) = println("dtest: " + x)
def someFunction(x:Int):Int = Deferrable { defer =>
defer(dtest(x))
println("before return")
defer(dtest(2*x))
x * 3
}
println(someFunction(3))
输出将是:
before return
dtest: 6
dtest: 3
3
我知道这可以通过不同的方式解决,但这实际上只是 Scala 支持延迟概念的一个例子,没有太多大惊小怪。
我想不出 Scala 特定的方式,但这不是等效的(尽管不是那么漂亮):
try {
// Do stuff
} finally {
// "defer"
}
不,Go 有这个结构正是因为它不支持异常并且没有try...finally
语法。
就个人而言,我认为它会引发维护噩梦。对 defer 的调用可以隐藏在函数的任何地方。即使负责任的编码人员将延迟放在要清理的东西旁边,我认为它不如一个finally
块那么清楚,至于它让凌乱的编码器做什么......至少finally
块将所有清理工作放在一个地方。
defer
与惯用的Scala相反。Scala 提供了控制程序流的一元方法,而defer
魔法根本没有贡献。Monads 提供了一个功能改进try...finally
,让你
defer
在这方面没有地位。