An attempt to use resources in Kotlin

When I tried to write the equivalent of Java try -with-resources code in Kotlin, it did not work for me.

I tried different options for the following:

 try (writer = OutputStreamWriter(r.getOutputStream())) { // ... } 

But not one works.

Does anyone know what should be used instead? Obviously, Kotlinโ€™s grammar has no definition for such a construction, but maybe I missed something. It defines the grammar for the try block as follows:

 try : "try" block catchBlock* finallyBlock?; 
+120
java extension-methods kotlin try-with-resources
Nov 17 '14 at 9:48
source share
3 answers

There is a use function ( src ) in kotlin stdlib.

How to use it:

 OutputStreamWriter(r.getOutputStream()).use { // by `it` value you can get your OutputStreamWriter it.write('a') } 
+181
Nov 17 '14 at 18:34
source share

TL; DR

No special syntax, but use function

Unlike Java, Kotlin has no special syntax for this. Instead, try-with-resources is suggested as a standard use library function.

 FileInputStream("filename").use { fis -> //or implicit 'it' //use stream here } 

Implementation use

 @InlineOnly public inline fun <T : Closeable?, R> T.use(block: (T) -> R): R { var closed = false try { return block(this) } catch (e: Exception) { closed = true try { this?.close() } catch (closeException: Exception) { } throw e } finally { if (!closed) { this?.close() } } } 

Closeable? this function defined as a common extension for all Closeable? types. Closeable is a Java interface that lets you try resources with Java SE7 .
The function accepts a functional literal block that is executed in try . As with try-with-resources in Java, Closeable closes in finally .

Also, crashes that occur inside the block are executed at close , where possible exceptions are literally "suppressed", simply ignoring them. This is different from try-with-resources because such exceptions may be thrown in a Java solution.

How to use it

The use extension is available for any type of Closeable , i.e. Closeable , readers, etc.

 FileInputStream("filename").use { //use your stream by referring to 'it' or explicitly give a name. } 

The part in braces that becomes block in use (lambda is passed as an argument here). After the block is done, you can be sure that the FileInputStream been closed.

+34
Oct 20 '17 at 6:40
source share

Edit : The following answer is still valid for Kotlin 1.0.x. For Kotlin 1.1, there is support for the standard library for Java 8 to support the lockable resource template.

For other classes that do not support the "use" function, I made the following home-made attempt with resources:

 package info.macias.kotlin inline fun <T:AutoCloseable,R> trywr(closeable: T, block: (T) -> R): R { try { return block(closeable); } finally { closeable.close() } } 

Then you can use it as follows:

 fun countEvents(sc: EventSearchCriteria?): Long { return trywr(connection.prepareStatement("SELECT COUNT(*) FROM event")) { var rs = it.executeQuery() rs.next() rs.getLong(1) } } 
+17
Mar 28 '16 at 10:21
source share



All Articles