【问题标题】:Is there a way to enforce that a kotlin function can be run only in the context of another function?有没有办法强制一个 kotlin 函数只能在另一个函数的上下文中运行?
【发布时间】:2020-05-12 16:13:55
【问题描述】:

我正在尝试回复这个答案Kotlin: Specify input-constraints in interface,我的想法是创建一个实现一些验证的函数,并允许验证函数仅在验证函数的上下文中调用。可能吗?这是我当前的代码:

interface MathThing {

    fun mathFunction(x: Int)
}

fun validationContext(x: Int, block: (Int) -> Unit){
    require(x > 0)
    block(x)
}

fun main() {

    val o = object : MathThing {
        override fun mathFunction(x: Int) {
            println(x)
        }
    }

    validationContext(-1, o::mathFunction)

}

【问题讨论】:

    标签: validation kotlin inheritance defensive-programming


    【解决方案1】:

    您的代码中的问题是您实际上并没有在一个块中调用o::mathFunction。你宁愿只是参考它。在这种情况下,它只是无操作。

    您可以通过将mathFunction 作为参数传递或在块内显式调用它来修复它:

    validateContext(1) {
        o.mathFunction(it)
    }
    // ok. => 1
    
    validateContext(1, o::mathFunction)
    // ok. => 1
    
    validateContext(-1, o::mathFunction)
    // validation error
    

    更新

    简短的回答是“不”。除非您的语言具有动态绑定的执行上下文,否则您不能轻易限制它。

    您可以尝试的是抛出错误,分析堆栈跟踪并确定所需的上下文函数是否在调用堆栈中。但这会非常缓慢和痛苦。

    我会做这样的事情,以确保函数始终得到验证

    val o = object : MathThing {
        override fun mathFunction(x: Int) = validateContext(x) {
            println(it)
        }
    }
    

    【讨论】:

    • 我的代码运行良好。在您的第一个示例中,您将 1 作为参数传递,这很好。如果您通过 -1,则会发生验证错误。问题不在于如何在块中调用函数,而在于如何强制它只能在特定函数的上下文中调用。
    • 我猜它没有。试试validateContext(1) { o::mathFunction },它显然不打印任何东西
    • 你是对的,验证仍然有效,但函数没有执行。谢谢指正,我会更新我的问题。但问题不在于它,正如我所说,它是关于强制 mathFunction 仅在 validateContext 内部调用的可能性。
    • 我的想法是有一些类似 launch launch builder 的东西,它只能在 CoroutineScope 上调用。本来打算做mathFunction的接收者的功能,但是好像不行。
    猜你喜欢
    • 2021-06-05
    • 2021-08-15
    • 2011-11-19
    • 2020-03-21
    • 2020-10-21
    • 2018-07-14
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    相关资源
    最近更新 更多