KotlinでJava try
- with-resourcesコードに相当するものを記述しようとしても、うまくいきませんでした。
次のさまざまなバリエーションを試しました。
try (writer = OutputStreamWriter(r.getOutputStream())) {
// ...
}
しかし、どちらも機能しません。
誰が代わりに何を使用すべきか知っていますか?どうやらKotlin文法 定義はありません このような構成体ですが、おそらく何かが欠けています。 tryブロックの文法を次のように定義します。
try : "try" block catchBlock* finallyBlock?;
Kotlin stdlibにはuse
- functionがあります( src )。
それを使用する方法:
OutputStreamWriter(r.getOutputStream()).use {
// by `it` value you can get your OutputStreamWriter
it.write('a')
}
特別な構文はありませんが、use
function
Javaとは対照的に、Kotlinにはこのための特別な構文はありません。代わりに、try-with-resourcesが標準ライブラリ関数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 の時点でtry-with-resourcesを許可します。
関数は、block
で実行される関数リテラルtry
を取ります。 Javaのtry-with-resourcesと同様に、Closeable
はfinally
でclosedを取得します。
また、block
の内部で発生した障害はclose
の実行につながります。可能な例外は、無視するだけで文字通り「抑制」されます。 Thisはtry-with-resourcesとは異なります。そのような例外は Java 'で要求できるためです解決策。
use
拡張機能は、すべての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」機能をサポートしない他のクラスについては、以下の自家製のtry-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()
}
}
その後、次の方法で使用できます。
fun countEvents(sc: EventSearchCriteria?): Long {
return trywr(connection.prepareStatement("SELECT COUNT(*) FROM event")) {
var rs = it.executeQuery()
rs.next()
rs.getLong(1)
}
}