Here’s a simple implementation (Be sure to try running and editing it right in the forum!):
class ResourceScope {
private val resources = mutableListOf<AutoCloseable>()
fun close() {
// In this case I chose to close with first-in-first-out.
// You could always extend this class to enable other kinds of closing strategies.
resources.forEach { it.close() }
}
fun AutoCloseable.autoClose() {
resources += this
}
}
fun using(block: ResourceScope.() -> Unit) {
val rs = ResourceScope()
try {
rs.block()
} finally {
rs.close()
}
}
fun main() {
//sampleStart
using {
val myResource = ExampleClosable("myResource").autoClose()
for (i in 0..5) {
ExampleClosable("$i").autoClose()
}
// error("Triggered error!") // Try uncommenting this to see that no resources are left un-closed.
println("Success!")
}
//sampleEnd
}
class ExampleClosable(val name: String) : AutoCloseable {
init {
println("Created resource $name")
}
override fun close() = println("Closing $name")
}
I’m sure there will be plenty of ways to improve on it. Like mentioned earlier in this thread, the ResourceScope
(others used ResourceHolder
) could be configured to handle resources in different ways allowing interesting solutions.