Kotlin kaynaklarıyla deneme


149

tryKotlin'de bir Java -with-resources koduyla eşdeğer yazmaya çalıştığımda, benim için işe yaramadı.

Aşağıdakilerin farklı varyasyonlarını denedim:

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

Ama ikisi de çalışmıyor.

Bunun yerine ne kullanılması gerektiğini bilen var mı? Görünüşe göre Kotlin dilbilgisinin böyle bir yapı için tanımı yok , ama belki bir şey eksik. Deneme bloğu için dilbilgisini aşağıdaki gibi tanımlar:

try : "try" block catchBlock* finallyBlock?;

Yanıtlar:


220

useKotlin stdlib'de ( src ) -fonksiyon vardır .

Bu nasıl kullanılır:

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

3
Uzatma yöntemlerini çok seviyorum. Yapabileceğiniz çok şey var ve ek dil özelliklerine gerek yok.
Kirill Rakhman

20
Buna ek olarak, aslında bir de elde etmek için bir uzantı özelliği var OutputStreamWriter:r.outputStream.writer.use { ... }
Damian Wieczorek

3
useUzantıyı gösteren referans dokümana bağlantı : kotlinlang.org/docs/reference/…
Javaru

1
Çoklu "kullanımı" daha iyi nasıl kullanabilirim? FileOutputStream(into).use { val mergingStream = BufferedOutputStream(it).use { } }
Ponomarenko Oleh

44

TL; DR: Özel bir sözdizimi yok, sadece bir işlev

Kotlin'in, Java'nın aksine, bunun için özel bir sözdizimi yoktur. Bunun yerine, kaynaklarla deneme , standart kitaplık işlevi olarak sunulur use.

FileInputStream("filename").use { fis -> //or implicit `it`
   //use stream here
} 

useuygulamaları

@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()
        }
    }
}

Bu işlev, tüm Closeable?türlerde genel bir uzantı olarak tanımlanır . CloseableJava'nın Java SE7'den itibaren kaynaklarla denemeye izin veren arayüzüdür . Bu işlev , a'da çalıştırılan bir değişmez işlevi alır . İle aynı denemede-ile-kaynaklar Java, alır kapalı bir yer .
blocktryCloseablefinally

Ayrıca, içeride meydana blockgelen arızalar close, olası istisnaların sadece görmezden gelinerek "bastırıldığı" infazlara yol açar . Bu , Java'nın çözümünde böyle istisnalar istenebileceğinden, kaynaklarla denemeden farklıdır .

Bu nasıl kullanılır

useUzatma herhangi mevcuttur Closeableokuyucular ve benzeri yani akarsu, tip.

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

Kıvırcık parantez içindeki parçası haline gelir ne blockde use(bir lambda burada bağımsız değişken olarak geçirilir). Blok tamamlandıktan sonra, FileInputStreamkapalı olduğundan emin olabilirsiniz .


16

Düzenleme : Aşağıdaki yanıt hala Kotlin 1.0.x için geçerlidir. Kotlin 1.1 için, kapatılabilir kaynak modelini desteklemek üzere Java 8'i hedefleyen standart bir kitaplık vardır.

"Kullan" işlevini desteklemeyen diğer sınıflar için, aşağıdaki ev yapımı kaynaklarla denemeleri yaptım:

package info.macias.kotlin

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

Sonra aşağıdaki şekilde kullanabilirsiniz:

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

1
Bu, nihayet maddeden atılan istisnalar ile düzgün bir şekilde ilgilenmez, bu da kaynaklarla deneme Java'ya eklenmesinin nedenlerinden biridir. Bu sadece basit bir try/finallyblok
Nikola Mihajlović

0

Bu StackOverflow gönderi "kotlin kapatılabilir örnek" için mevcut arama sonuçlarının en üstüne yakın olduğu ve diğer cevapların (ya da resmi belgelerin) hiçbirinin nasıl genişletileceğini Closeable(aka java.io.Closeable) açıklayacağını açıkladığından , bir örnek ekleyeceğimi düşündüm genişleten kendi sınıfını yapmak için nasıl Closeable. Bu böyle devam ediyor:

import java.io.Closeable

class MyServer : Closeable {
    override fun close() {
        println("hello world")
    }
}

Ve sonra kullanmak için:

fun main() {
    val s = MyServer()
    s.use {
        println("begin")
    }
    println("end")
}

Buradaki Kotlin Playground'daki bu örneğe bakın .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.