Ответ 1
В kotlin stdlib есть use
-функция (src).
Как использовать его:
OutputStreamWriter(r.getOutputStream()).use {
// by `it` value you can get your OutputStreamWriter
it.write('a')
}
Когда я попытался написать эквивалент Java try
-с-ресурсов код в Котлин, он не работает для меня.
Я пробовал разные варианты следующего:
try (writer = OutputStreamWriter(r.getOutputStream())) {
// ...
}
Но ни один не работает.
Кто-нибудь знает, что следует использовать вместо этого? Очевидно, у грамматики Котлина нет определения для такой конструкции, но, возможно, я что-то упустил. Он определяет грамматику для блока try следующим образом:
try : "try" block catchBlock* finallyBlock?;
В kotlin stdlib есть use
-функция (src).
Как использовать его:
OutputStreamWriter(r.getOutputStream()).use {
// by `it` value you can get your OutputStreamWriter
it.write('a')
}
Нет специального синтаксиса, но use
функцию
В отличие от Java, Kotlin не имеет специального синтаксиса для этого. Вместо этого попробуйте-с-ресурсами, предлагается в качестве стандартной функции библиотеки 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()
}
}
}
Эта функция определяется как общее расширение для всех Closeable?
типы. Closeable
является интерфейсом Java, который позволяет попробовать ресурсы с Java SE7.
Функция принимает функциональный литеральный block
который выполняется в try
. Как и в случае с try-with-resources в Java, Closeable
закрывается в finally
.
Также сбои, происходящие внутри block
приводят к выполнению при close
, где возможные исключения буквально "подавляются", просто игнорируя их. Это отличается от try-with-resources, потому что такие исключения могут быть запрошены в решении Java.
Расширение use
доступно для любого типа Closeable
, т. Closeable
, читателей и т.д.
FileInputStream("filename").use {
//use your stream by referring to 'it' or explicitly give a name.
}
Часть в фигурных скобках, что становится block
в use
(лямбда передается в качестве аргумента здесь). После того, как блок сделан, вы можете быть уверены, что FileInputStream
был закрыт.
Изменить: Следующий ответ все еще действителен для Kotlin 1.0.x. Для Kotlin 1.1 существует поддержка стандартной библиотеки, предназначенной для Java 8, для поддержки шаблона закрываемых ресурсов.
Для других классов, которые не поддерживают функцию "use", я сделал следующую самодельную попытку с ресурсами:
package info.macias.kotlin
inline fun <T:AutoCloseable,R> trywr(closeable: T, block: (T) -> R): R {
try {
return block(closeable);
} finally {
closeable.close()
}
}
Тогда вы можете использовать его следующим образом:
fun countEvents(sc: EventSearchCriteria?): Long {
return trywr(connection.prepareStatement("SELECT COUNT(*) FROM event")) {
var rs = it.executeQuery()
rs.next()
rs.getLong(1)
}
}