Lorsque j'ai essayé d'écrire un équivalent d'un code Java try
avec ressources, dans Kotlin, cela ne fonctionnait pas pour moi.
J'ai essayé différentes variantes de ce qui suit:
try (writer = OutputStreamWriter(r.getOutputStream())) {
// ...
}
Mais ni fonctionne.
Est-ce que quelqu'un sait ce qui devrait être utilisé à la place? Apparemment, la grammaire Kotlin n'a pas de définition pour une telle construction, mais peut-être qu'il me manque quelque chose. Il définit la grammaire du bloc try comme suit:
try : "try" block catchBlock* finallyBlock?;
Il y a use
- fonction dans kotlin stdlib ( src ).
Comment l'utiliser:
OutputStreamWriter(r.getOutputStream()).use {
// by `it` value you can get your OutputStreamWriter
it.write('a')
}
Pas de syntaxe spéciale, mais use
function
Kotlin, contrairement à Java, n'a pas de syntaxe spéciale pour cela. Au lieu de cela, try-with-resources, est proposé comme fonction de bibliothèque standard use
.
FileInputStream("filename").use { fis -> //or implicit `it`
//use stream here
}
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()
}
}
}
Cette fonction est définie comme une extension générique sur tous les Closeable?
les types. Closeable
est le interface de Java qui permet try-with-resources à partir de Java SE7 .
La fonction prend une fonction littérale block
qui est exécutée dans un try
. Comme avec try-with-resources en Java, le Closeable
obtient fermé dans un finally
.
De plus, les échecs à l'intérieur de block
conduisent à close
exécutions, où les exceptions possibles sont littéralement "supprimées" en les ignorant. This est différent de try-with-resources, car de telles exceptions peuvent être demandées dans la solution de Java .
L’extension use
est disponible sur n’importe quel type de Closeable
, à savoir les flux, les lecteurs, etc.
FileInputStream("filename").use {
//use your stream by referring to `it` or explicitly give a name.
}
La partie entre accolades est ce qui devient block
dans use
(un lambda est passé comme argument ici). Une fois le blocage effectué, vous pouvez être sûr que FileInputStream
a été fermé.
Edit: La réponse suivante est toujours valable pour Kotlin 1.0.x. Pour Kotlin 1.1, une bibliothèque standard prend en charge Java 8 pour prendre en charge le modèle de ressource pouvant être fermé).
Pour les autres classes qui ne prennent pas en charge la fonction "use", j'ai effectué les try-with-resources maison suivants:
package info.macias.kotlin
inline fun <T:AutoCloseable,R> trywr(closeable: T, block: (T) -> R): R {
try {
return block(closeable);
} finally {
closeable.close()
}
}
Ensuite, vous pouvez l'utiliser de la manière suivante:
fun countEvents(sc: EventSearchCriteria?): Long {
return trywr(connection.prepareStatement("SELECT COUNT(*) FROM event")) {
var rs = it.executeQuery()
rs.next()
rs.getLong(1)
}
}