web-dev-qa-db-ja.com

Kotlinのリソースを試してみてください

KotlinでJava try- with-resourcesコードに相当するものを記述しようとしても、うまくいきませんでした。

次のさまざまなバリエーションを試しました。

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

しかし、どちらも機能しません。

誰が代わりに何を使用すべきか知っていますか?どうやらKotlin文法 定義はありません このような構成体ですが、おそらく何かが欠けています。 tryブロックの文法を次のように定義します。

try : "try" block catchBlock* finallyBlock?;
124
Alex

Kotlin stdlibにはuse- functionがあります( src )。

それを使用する方法:

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

TL; DR

特別な構文はありませんが、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と同様に、Closeablefinallyclosedを取得します。

また、blockの内部で発生した障害はcloseの実行につながります。可能な例外は、無視するだけで文字通り「抑制」されます。 Thistry-with-resourcesとは異なります。そのような例外は Java 'で要求できるためです解決策。

それを使用する方法

use拡張機能は、すべてのCloseable型(ストリーム、リーダーなど)で使用できます。

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

中括弧内の部分は、blockuseになります(ラムダは引数としてここに渡されます)。ブロックが完了すると、FileInputStreamが閉じられたことを確認できます。

35
s1m0nw1

編集:次の応答は、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)
    }
}
17
Mario