如何在 Scala 中编写类析构函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4002343/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:31:49  来源:igfitidea点击:

How to write a class destructor in Scala?

scaladestructor

提问by Ivan

I'd like to have a FileWriter opened during the whole time a class instance exists. So I need to close it in a destructor. But how to specify a destructor in Scala?

我想在类实例存在的整个时间内打开一个 FileWriter。所以我需要在析构函数中关闭它。但是如何在 Scala 中指定析构函数?

回答by Kris Nuttycombe

You might be interested to check out Josh Suereth's scala-arm project, which provides both monadic and delimited-continuation based resource management for just this source of use: http://github.com/jsuereth/scala-arm

您可能有兴趣查看 Josh Suereth 的 scala-arm 项目,该项目提供基于 monadic 和基于分隔继续的资源管理,仅用于此使用源:http: //github.com/jsuereth/scala-arm

If you really think that you need a destructor (i.e. because you think you need to create the object and then hand it off and never see it again) I'd recommend reconsidering your application architecture instead... there is simply no way to make this work reliably on the JVM.

如果您真的认为您需要一个析构函数(即因为您认为您需要创建对象,然后将其传递出去并且再也看不到它),我建议您重新考虑您的应用程序架构...这在 JVM 上可靠地工作。

回答by F. P. Freely

Here's a handy utility method I use frequently. I find that it unclutters my code nicely.

这是我经常使用的一个方便的实用方法。我发现它很好地整理了我的代码。

def closer [T, C <: Closeable] (c : C) (f : C => T) : T = 
    try f (c)
    finally c.close

Using it is dead simple. The example, below, consumes an input stream from a URLConnection. Instead of connection.getInputStream you could create any arbitrary stream, of course (or, more generally, any arbitrary closeable object).

使用它非常简单。下面的示例使用来自 URLConnection 的输入流。当然,您可以创建任意流,而不是 connection.getInputStream(或者,更一般地说,任意可关闭的对象)。

val bytes = closer (connection.getInputStream) { istream =>
        val bytes = new ByteArrayOutputStream ()
        val buffer : Array [Byte] = new Array (1024)
        Iterator.continually (istream read buffer).takeWhile (_ > 0).foreach (bytes write (buffer, 0, _))
        bytes.toByteArray
    }

This version will operate on anything with a close method (needn't implement Closeable or anything else).

这个版本将使用 close 方法操作任何东西(不需要实现 Closeable 或其他任何东西)。

def autoClose[R <: {def close()}, T](resource: R)(use: R => T): T = {
  try use(resource)
  // Don't want an NPE here masking an exception from use.
  finally Option(resource).foreach(_.close())
}

Here are some implicit classes to do the job.

这里有一些隐式类来完成这项工作。

implicit class AutoCloseBracket[R <: Closeable](resource: R) {
  def autoClose[V](use: R => V): V = try use(resource) finally resource.close()
}
implicit class AutoCloseableBracket[R <: AutoCloseable](resource: R) {
  def autoClose[V](use: R => V): V = try use(resource) finally resource.close()
}

回答by Marcelo Cantos

Scala doesn't have destructors. It has finalizers, like Java, but they're not the same thing at all. There is also an interesting blog series in emulating C#'s usingkeyword in Scala here:

Scala 没有析构函数。它有终结器,如 Java,但它们根本不是一回事。这里还有一个有趣的博客系列using在 Scala中模拟 C# 的关键字:

回答by Matthew Flaschen

As I noted above, Java has an existing Closeableinterface specifically for IO, which you could adopt. This doesn't provide any sugar, but it will help people use your class correctly.

正如我上面提到的,Java 有一个Closeable专门用于 IO的现有接口,您可以采用它。这不提供任何糖分,但它会帮助人们正确使用您的课程。

In Java 7, Closeablewill be a subinterface of AutoCloseable. AutoCloseableis a more general interface for any resource that needs to be closed after use while potentially throwing an exception. it is part of the planned Automatic Resource Managementsupport in Java 7. Less relevant to your question (since you're using Scala), there is also supposed to be new Java syntax(an extension of existing try blocks) for this scenario.

在 Java 7 中,Closeable将是AutoCloseable. AutoCloseable是一个更通用的接口,用于在使用后需要关闭同时可能引发异常的任何资源。它是Java 7 中计划的自动资源管理支持的一部分。与您的问题不太相关(因为您使用的是 Scala),对于这种情况,还应该有新的Java 语法(现有 try 块的扩展)。