코 틀린의 자원 활용


147

tryKotlin에서 Java 자원 코드 와 동등한 코드 를 작성하려고 시도했지만 작동하지 않았습니다.

나는 다음과 같은 다른 변형을 시도했다.

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

그러나 둘 다 작동하지 않습니다.

누구 대신 사용해야하는지 알고 있습니까? 분명히 Kotlin 문법 에는 그러한 구문에 대한 정의 가 없지만 어쩌면 뭔가 빠졌습니다. try 블록의 문법을 다음과 같이 정의합니다.

try : "try" block catchBlock* finallyBlock?;

답변:


219

usekotlin stdlib ( src ) 에는 기능이 있습니다 .

사용 방법:

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

3
나는 확장 방법을 너무 좋아합니다. 할 수있는 일이 많고 추가 언어 기능이 필요하지 않습니다.
Kirill Rakhman

20
여기에 추가하면, 실제로를 얻기 위해 확장 등록이 OutputStreamWriter뿐만 아니라 :r.outputStream.writer.use { ... }
데미안 조렉

3
use확장 을 보여주는 참조 문서 링크 : kotlinlang.org/docs/reference/…
Javaru

1
더 나은 방법으로 다중 "사용"을 사용하려면 어떻게해야합니까? FileOutputStream(into).use { val mergingStream = BufferedOutputStream(it).use { } }
Ponomarenko Oleh

43

TL; DR : 특별한 구문이없고 함수일뿐입니다

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?유형 에서 일반 확장으로 정의됩니다 . Java SE7 부터 리소스사용해 볼 수있는 CloseableJava 인터페이스 입니다 . 이 함수 에서 실행되는 함수 리터럴 을 사용합니다 . 와 동일 시도 -과 - 자원 자바의가 됩니다 폐쇄 A의 .
blocktryCloseablefinally

또한 내부에서 발생하는 실패 blockclose실행 으로 이어지는데, 예외를 무시함으로써 가능한 예외가 문자 그대로 "억제"됩니다. 이것은 다른 시도 -과 - 자원 과 같은 예외가에서 요구 될 수 있기 때문에, 자바 의 솔루션입니다.

사용 방법

use확장은 볼 수 Closeable독자 등등, 즉 스트림을 입력합니다.

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

둥근 괄호 안의 부분하게 무엇인가 blockuse(람다 여기서 인수로 전달된다). 블록이 완료된 후 FileInputStream닫혔 는지 확인할 수 있습니다 .


16

편집 : 다음 응답은 여전히 ​​Kotlin 1.0.x에 유효합니다. Kotlin 1.1의 경우, 닫기 가능한 자원 패턴을 지원하기 위해 Java 8을 대상으로하는 표준 라이브러리가 지원됩니다.

"사용"기능을 지원하지 않는 다른 클래스의 경우 다음과 같은 수제 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)
    }
}

1
try-with-resources가 Java에 추가 된 이유 중 하나 인 finally 절에서 발생한 예외를 올바르게 처리하지 못합니다. 이것은 단지 간단한 try/finally블록입니다
Nikola Mihajlović

0

이 StackOverflow 게시물은 "kotlin closeable example"에 대한 현재 검색 결과의 최상위에 가깝지만 다른 답변 (공식 문서 또는 다른 문서) 중 어느 것도 확장 방법 Closeable(aka java.io.Closeable) 을 명확하게 설명하지 못하기 때문에 예제를 추가 할 것이라고 생각했습니다. 자신 만의 클래스를 만드는 방법에 대한 설명 Closeable. 다음과 같이 진행됩니다.

import java.io.Closeable

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

그리고 그것을 사용하려면 :

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

여기 Kotlin Playground에서이 예를 참조 하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.