Tente com recursos no Kotlin
1. Introdução
Idiomas gerenciados, como aqueles direcionados à JVM, manipulam automaticamente o recurso mais comum: memória.
No entanto, precisamos lidar com todos os tipos de recursos, não apenas com memória: arquivos, conexões de rede, fluxos, janelas etc. E,just like memory, those need to be released when no longer needed.
Neste artigo, veremos como os recursos podem ser gerenciados automaticamente no Kotlin e como isso difere deJava’s try-with-resources construct.
Se você quiser pular a teoria,jump straight to the example.
2. Gestão Automática de Recursos
Podemos distinguir três fases diferentes ao trabalhar com recursos em Java (pseudocódigo):
resource = acquireResource()
try {
useResource(resource)
} finally {
releaseResource(resource)
}
Se a linguagem ou biblioteca é responsável por liberar o recurso (a partefinally), então a chamamos deAutomatic Resource Management. Tal recursorelieves us from having to remember to free a resource.
Além disso, como o gerenciamento de recursos geralmente está vinculado a um escopo de bloco, se lidarmos com mais de um recurso ao mesmo tempo, eles sempre serão liberados na ordem correta.
Em Java, os objetos que contêm um recurso e são elegíveis para gerenciamento automático de recursos implementam uma interface específica:Closeable para recursos relacionados a E / S eAutoCloseable.
Além disso, o Java 7 adaptou a interfaceCloseable pré-existente para estenderAutoCloseable.
Portanto, Kotlin tem o mesmo conceito de detentores de recursos: ou seja, objetos que implementamCloseable ouAutoCloseable.
3. A funçãouse em Kotlin
Para gerenciar recursos automaticamente, algumas linguagens têm uma construção dedicada: Java 7 introduziutry-with-resources, por exemplo, enquanto C # temthe using keyword.
Às vezes, eles nos oferecem um padrão, comoRAII in C++. Em alguns outros casos, eles nos fornecem um método de biblioteca.
Kotlin se enquadra na última categoria.
Por design, édoesn’t have a language construct akin to try-with-resources in Java.
Em vez disso, podemos encontrar um método de extensão chamadouse em sua biblioteca padrão.
Veremos em detalhes mais tarde. Por enquanto, só precisamos saber que todo objeto de suporte de recurso possui o métodouse que podemos invocar.
3.1. Como usá-lo
Um exemplo simples:
val writer = FileWriter("test.txt")
writer.use {
writer.write("something")
}
Podemos invocar a funçãouse em qualquer objeto que implementeAutoCloseable ouCloseable, assim como com try-with-resources em Java.
O método pega uma expressão lambda, a executa e descarta o recurso (chamandoclose() nela) sempre que a execução deixa o bloco, normalmente ou com uma exceção.
Portanto, neste caso, depois deuse,, owriter não pode mais ser usado, porque o Kotlin o fechou automaticamente.
3.2. Uma forma mais curta
No exemplo acima, para maior clareza, usamos uma variável chamadawriter, criando assim um fechamento.
No entanto,use aceita uma expressão lambda com um único parâmetro– o objeto que contém o recurso:
FileWriter("test.txt")
.use { w -> w.write("something") }
Dentro do bloco, também podemos usar a variável implícitait:
FileWriter("test.txt")
.use { it.write("something") }
Então, como podemos ver, não temos que dar ao objeto um nome explícito. No entanto, geralmente é uma boa idéia deixar claro, em vez de escrever código excessivamente conciso.
3.3. A definição deuse()
Vejamos a definição da funçãouse em Kotlin, conforme encontrada em sua biblioteca padrão:
public inline fun T.use(block: (T) -> R): R
Podemos ver, na parte<T : Closeable?, R>, queuse is defined as an extension function on Java’s Closeable interface.
Mais sobre os métodos de extensão podem ser encontrados emour introductory article.
Claro,the use function is documented como parte da biblioteca padrão do Kotlin.
3.4. Closeable vsAutoCloseable
Se prestarmos mais atenção ao exemplo da seção anterior, podemos ver que a assinatura da funçãouse é definida apenas na interfaceCloseable. This is because Kotlin’s standard library targets Java 6.
Nas versões Java anteriores a 7,AutoCloseable não existia e, claro,Closeable não o estendia.
Na prática, as classes que implementamAutoCloseable mas nãoCloseable são raras. Ainda assim, podemos encontrar um deles.
Nesse caso, só temos que adicionar uma dependência nas extensões Kotlin para Java 7, 8 ou qualquer versão que pretendemos:
org.jetbrains.kotlin
kotlin-stdlib-jdk8
A versão mais recente da dependência pode ser encontrada emMaven Central.
Isso nos dá outra função de extensãouse definida na interfaceAutoCloseable:
public inline fun T.use(block: (T) -> R): R
4. Conclusão
Neste tutorial, vimos como uma função de extensão simples na biblioteca padrão do Kotlin é tudo o que precisamos para gerenciar todos os tipos de recursos conhecidos pela JVM automaticamente.
A implementação de todos esses exemplos e trechos de código pode ser encontrada emthe GitHub project - este é um projeto Maven, portanto, deve ser fácil de importar e executar como está.