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?
In Scala, we are allowed to make a primary constructor private by using a private keyword in between the class name and the constructor parameter-list.
In Scala, an object of a class is created using the new keyword. The syntax of creating object in Scala is: Syntax: var obj = new Dog();
Scala ConstructorThere are two types of constructor in Scala – Primary and Auxiliary. Not a special method, a constructor is different in Scala than in Java constructors. The class' body is the primary constructor and the parameter list follows the class name.
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
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.
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).
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).
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()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With