2016-03-28 23 views
5

Kotlin die use Funktion für Closeable Objekte liefert, aber es scheint sie vergessen AutoCloseable zu berücksichtigen (z DB Prepared Statements) für den Try-with-Ressourcen voll Java-Äquivalent.Meine eigene Lösung für Kotlin des Try-with-Ressourcen Abwesenheit

Ich habe die nächste "home-made" Lösung implementiert:

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

Dann können Sie es das nächste Art und Weise verwenden:

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

ich Kotlin bin neu, und ich möchte zu wissen, ob ich etwas wichtiges in meiner eigenen Lösung vermisse, das mir Probleme/Leckagen in einer Produktionsumgebung geben könnte.

+3

der Grund, warum sie nicht unterstützen 'AutoClosable' out-of-the-Box ist, dass sie immer noch Java8 Unterstützung zu implementieren sowie JDK8 Klassen – voddan

+0

Sie könnten immer unterstützen kopieren Sie die Quelle für 'use' und Änderung' Closeable' zu ​​'AutoCloseable' (siehe [ReadWrite.kt: 145-177] (https://github.com/JetBrains/kotlin/blob/8549ec7645ff6db4d5fede2c43034be66683561a/libraries/stdlib/src/ Kotlin/io/ReadWrite.kt # L145-L177). – mfulton26

+0

Betrachten Java 8 für das Muster. Sie können es hier finden http://stackoverflow.com/a/43269795/2463695 –

Antwort

7

Ihre Umsetzung wird gut funktionieren, aber es ist anders von einer Standard-Anprobe mit-Ressourcen Implementierung. Wenn Sie wollen, dass es wie in Java arbeiten Sie so etwas tun sollte:

inline fun <T : AutoCloseable, R> trywr(closeable: T, block: (T) -> R): R { 
    var currentThrowable: java.lang.Throwable? = null 
    try { 
    return block(closeable) 
    } catch (throwable: Throwable) { 
    currentThrowable = throwable as java.lang.Throwable 
    throw throwable 
    } finally { 
    if (currentThrowable != null) { 
     try { 
     closeable.close() 
     } catch (throwable: Throwable) { 
     currentThrowable.addSuppressed(throwable) 
     } 
    } else { 
     closeable.close() 
    } 
    } 
} 

UPDATE:

Wie mfulton26 wies darauf hin, in seiner commentkotlin.Throwable nicht addSuppressed(Throwable) Methode enthält, so müssen wir werfen kotlin.Throwable zu java.lang.Throwable, damit der Code funktioniert.

+1

es gibt keine 'addSuppress (Throwable)' Methode auf 'kotlin.Thro wable' und du kannst 'java.lang.Throwable' nicht in einem Kotlin-try-catch verwenden, also wie kompiliert dieser Code (außer' s/throwable/'throwable /')? – mfulton26

+0

@ mfulton26 Ich glaube, es sollte "Ausnahme" anstelle von "Throwable" sein. – Kiskae

+1

@ mfulton26 Danke, das ist ein guter Punkt. Der Code wurde aktualisiert, damit er kompiliert werden kann. – Michael

0

Ich denke, was Sie wollen, ist use() wie auf Closable definiert.

2

Seit Kotlin 1.1, .use hat eine AutoCloseable Implementierung.

@SinceKotlin("1.1") 
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER") 
@kotlin.internal.InlineOnly 
public inline fun <T : AutoCloseable?, R> T.use(block: (T) -> R): R { 
    var exception: Throwable? = null 
    try { 
     return block(this) 
    } catch (e: Throwable) { 
     exception = e 
     throw e 
    } finally { 
     this.closeFinally(exception) 
    } 
} 

Kopiert von source