使用另一个内联lambda参数调用内联lambda

使用另一个内联lambda参数调用内联lambda,lambda,kotlin,inline,higher-order-functions,Lambda,Kotlin,Inline,Higher Order Functions,我试图使这个高阶Kotlin函数: private inline fun <T> reentrant(entered: ThreadLocal<Boolean>, block: () -> T, enter: (() -> T) -> T) = if (entered.get()) block() else { try { entered.set(true) enter(bl

我试图使这个高阶Kotlin函数:

private inline fun <T> reentrant(entered: ThreadLocal<Boolean>, block: () -> T, enter: (() -> T) -> T) =
    if (entered.get()) block()
    else {
        try {
            entered.set(true)
            enter(block)
        } finally {
            entered.set(false)
        }
    }
但是,显然不允许构造
enter(block)
非法使用内联参数block


因为这里的一切都是内联的,我认为这在技术上应该是可能的。编译器不支持此功能吗?或者,到底有什么方法可以做到这一点吗?

如果执行类似于
val x=block
的操作,则会出现相同的错误。如果您试图将Kotlin反编译为字节码,您将看到的最后一个错误是:

尝试访问跳过的参数

我认为关键是当你内联一些东西时,它不再是代码中的对象,所以你不能直接引用它。显然,只要调用函数本身就可以了,因为它已经内联到调用代码中了


这将得到更详细的解释。当函数参数内联时,不会创建
函数
对象。我想知道在你的问题中,你的意思是否是:“为什么编译器不内联
输入
,然后内联
”,我猜原因是,这将假定
输入
所做的一切都是调用
。但如果没有呢?如果它想存储对它的引用,例如在将来某个时候调用的函数列表中,该怎么办?它无法执行此操作,因为没有可供其引用的
函数
对象。

错误消息显示“向参数声明添加noinline修饰符”。如果将此修饰符添加到
参数,它现在将编译。你想避免这个,还是那就足够了?是的,这就是我想要避免的。我刚刚意识到内联一个两次调用的lambda不是一个好主意,但我仍然对为什么这在概念上是不可能的感兴趣。
reentrant(fooing, block) { b ->
  try {
    log("Entering a state of foo")
    b()
    // sidenote: while writing this question it dawned on me,
    //           that i could just calll the captured `block` here,
    //           as a workaround
  } finally {
    log("Foo nevermore")
  }
}