Try-with-resources en Kotlin

Cuando traté de escribir un código equivalente de try-with-resources en Kotlin, no funcionó para mí.

Intenté diferentes variaciones de lo siguiente:

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

Pero ninguno funciona.

¿Alguien sabe qué se debe usar en su lugar? Aparentemente la gramática de Kotlin no tiene definición para tal construcción, pero puede ser que me falta algo. Define la gramática para try block de la siguiente manera:

 try : "try" block catchBlock* finallyBlock?; 

    Hay una function de use en kotlin stdlib ( src ).

    Cómo usarlo:

     OutputStreamWriter(r.getOutputStream()).use { // by `it` value you can get your OutputStreamWriter it.write('a') } 

    Editar : la siguiente respuesta sigue siendo válida para Kotlin 1.0.x. Para Kotlin 1.1, se admite una biblioteca estándar que se dirige a Java 8 para admitir el patrón de resources que se puede cerrar.

    Para otras classs que no admiten la function "usar", he hecho los siguientes try-with-resources caseros:

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

    Entonces puedes usarlo de la siguiente manera:

     fun countEvents(sc: EventSearchCriteria?): Long { return trywr(connection.prepareStatement("SELECT COUNT(*) FROM event")) { var rs = it.executeQuery() rs.next() rs.getLong(1) } } 

    Use el use en use lugar

    Kotlin no tiene una syntax especial para esto. En cambio, try-with-resources se ofrece como el use function de biblioteca estándar.

    La implementación de 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() } } } 

    Esta pequeña function se define como una extensión genérica en todos los Closeable? types. Closeable es la interfaz de Java que permite probar con resources a partir de Java SE7 .
    La function toma un block literal de function que se ejecuta en un try . Igual que con try-with-resources en Java, el Closeable se cierra por finally .

    También las fallas en block llevan a ejecuciones cerradas, donde las posibles excepciones son literalmente "suprimidas" simplemente ignorándolas. Esto es diferente de try-with-resources , porque tales excepciones se pueden solicitar en la solución de Java .

    Cómo utilizar

    La extensión de use está disponible en cualquier tipo de Closeable , es decir, transmisiones, lectores, etc.

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

    La parte en {} es lo que se convierte en block en use (una lambda se pasa como argumento). Una vez hecho el locking, puede estar seguro de que FileInputStream está cerrado.