【问题标题】:Kotlin closure to solve logical and operationKotlin闭包解决逻辑和操作
【发布时间】:2018-05-11 21:01:09
【问题描述】:

我想创建一个闭包,它采用所有布尔表达式和方法,给出最终结果 像这样的

  myAnd{
    23<34
    false
    someFunction() //returns true
    }

所以答案是错误的

我的解决方案是这样的

fun myAnd(vararg flags: Boolean) = flags.all { it }

myAnd(true , false ,someFunction())

但是这个解决方案在使用和操作符时不会产生短路的力量

【问题讨论】:

    标签: kotlin closures


    【解决方案1】:

    使用block实现短路和

    fun someFunction() = true
    
    fun and(vararg parameters: ()->Boolean): Boolean {
        return parameters.all { it() }
    }
    
    fun main(args: Array<String>) {
        and (
                {23<34},
                {false},
                ::someFunction
        )
    }
    

    这是通过将每个谓词作为一个块传递来实现的,这意味着它们可以被一个一个地评估,如果它们中的任何一个返回 false,那么所有将立即返回 false,从而使其余的短路。

    【讨论】:

    • 感谢您的回答,但有什么方法可以通过使用闭包而不是将 lambdas 作为方法的参数传递来使其符合习惯
    • 更惯用的解决方案。你真的想要 3 个闭包,而不是 1 个,因为像这样使用单个闭包等效于 { someFunction() }:它只计算前 2 行并忽略它们的值。
    【解决方案2】:

    我能想到一个快速的解决方案,可以实现以下用途:

    val boolResult: Boolean = myAnd {
        + (23 < 34)
        + false
        + someFunction() //returns true
    }
    

    以下是相关代码:

    fun myAnd(bb: BooleanBuilder.() -> Unit) = BooleanBuilder().apply { bb() }.result
    
    class BooleanBuilder {
        var bools = listOf<Boolean>()
        operator fun Boolean.unaryPlus() {
            bools += this
        }
    
        fun result() = bools.all { it }
    }
    

    说明:这是自定义 DSL 的轻量级示例。其中有趣的部分是BooleanBuilder.() -&gt; Unit,一个function literal with receiver,这样我就可以传递一个在BooleanBuilder(lambda 的接收器)范围内的lambda。这是使用成员扩展Boolean.unaryPlus 所必需的,它再次启用+ boolean 的使用,如图所示。

    【讨论】:

    • 此解决方案按预期对我有用,但请您稍微解释一下 myAdd 函数及其工作原理以及此解决方案不会短路
    • 添加了简要说明
    猜你喜欢
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    • 2011-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多