使用另一个内联lambda参数调用内联lambda
我试图使这个高阶Kotlin函数:使用另一个内联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
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")
}
}