首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >尝试-具有-资源/使用/多种资源

尝试-具有-资源/使用/多种资源
EN

Stack Overflow用户
提问于 2018-04-20 14:19:12
回答 3查看 7.6K关注 0票数 22

我使用的是Java,它大量使用自动关闭接口,因此在中也是如此。但是,在Java中,您可以指定

代码语言:javascript
复制
try (res1, res2, res3...) {
  ...
}

我们有办法使用多个资源吗?它看起来像众所周知的回调-地狱:

代码语言:javascript
复制
val database = Databases.openDatabase(dbFile)

database.use {
  database.createResource(ResourceConfiguration.Builder(resPathName, config).build())

  val resMgr = database.getResourceManager(ResourceManagerConfiguration.Builder(resPathName).build())

  resMgr.use {
    val wtx = resMgr.beginNodeWriteTrx()

    wtx.use {
      wtx.insertSubtreeAsFirstChild(XMLShredder.createStringReader(resFileToStore))
    }
  }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-04-21 06:08:21

为了简单起见,我将使用A、B和C作为链式自动闭锁。。

代码语言:javascript
复制
import java.io.Closeable

open class MockCloseable: Closeable {
    override fun close() = TODO("Just for compilation")
}
class A: MockCloseable(){
    fun makeB(): B = TODO()
}
class B: MockCloseable(){
    fun makeC(): C = TODO()

}
class C: MockCloseable()

使用用途

这个应该是这样的:

代码语言:javascript
复制
A().use {a ->
    a.makeB().use {b -> 
        b.makeC().use {c -> 
            println(c)
        }
    }
}

使用包装器使链使用函数

定义

代码语言:javascript
复制
class ChainedCloseable<T: Closeable>(val payload: T, val parents: List<Closeable>) {
    fun <U> use(block: (T)->U): U {
        try {
            return block(payload)
        } finally {
            payload.close()
            parents.asReversed().forEach { it.close() }
        }
    }

    fun <U: Closeable> convert(block: (T)->U): ChainedCloseable<U> {
        val newPayload = block(payload)
        return ChainedCloseable(newPayload, parents + payload)
    }
}

fun <T: Closeable, U: Closeable> T.convert(block:(T)->U): ChainedCloseable<U> {
    val new = block(this)

}

使用

代码语言:javascript
复制
A()
    .convert(A::makeB)
    .convert(B::makeC)
    .use { c ->
         println(c)
    }

这使您可以避免不得不以创建包装器对象为代价进行深度嵌套。

票数 5
EN

Stack Overflow用户

发布于 2018-04-20 15:18:17

没有标准的解决方案。如果一开始就准备好了所有的Closable实例,您可以使用自己定义的方法来处理它们,比如这篇博客文章这个储存库演示( 这里是导致后者的官方论坛上的讨论)。

然而,在您的示例中,如果后续对象依赖于前面的对象,那么这些对象都不像常规的try-with-resources那样适用。

我唯一能提出的建议是为自己定义隐藏嵌套use调用的助手函数,如果可能的话,立即将您置于这些资源获取的第二/第三层/第九层。

票数 12
EN

Stack Overflow用户

发布于 2018-04-22 03:35:11

这方面的另一个办法是:

代码语言:javascript
复制
val CloseableContext = ThreadLocal<MutableList<AutoCloseable>>()

inline fun scopeDef(inScope: () -> Unit) {
    val oldContext = CloseableContext.get()

    val currentContext = mutableListOf<AutoCloseable>()

    CloseableContext.set(currentContext)

    try {
        inScope()
    }
    finally {
        for(i in (currentContext.size - 1) downTo 0) {
            try {
                currentContext[i].close()
            }
            catch(e: Exception) {
                // TODO: Record as suppressed exception
            }
        }
        CloseableContext.set(oldContext)
    }
}

fun <T: AutoCloseable> autoClose(resource: T): T {
    CloseableContext.get()?.add(resource) ?: throw IllegalStateException(
            "Calling autoClose outside of scopeDef is forbidden")

    return resource
}

用法:

代码语言:javascript
复制
class Close1(val name: String): AutoCloseable {
    override fun close() {
        println("close $name")
    }
}

fun main(args : Array<String>) {
    scopeDef {
        val c1 = autoClose(Close1("1"))

        scopeDef {
            val c3 = autoClose(Close1("3"))
        }

        val c2 = autoClose(Close1(c1.name + "+1"))

    }
}

输出:

代码语言:javascript
复制
close 3
close 1+1
close 1
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49943806

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档