【问题标题】:Scala - two operand or/and functionsScala - 两个操作数或/和函数
【发布时间】:2021-08-26 17:51:14
【问题描述】:

在 Java 中有静态和/或函数,它们接收两个布尔操作数并返回正确的结果:logicalAndlogicalOr(都位于 java.lang.Boolean)[1]:

public static boolean logicalAnd(boolean a, boolean b)
public static boolean logicalOr(boolean a, boolean b)

我正在 Scala 标准库中寻找类似的概念。有吗?

编辑

我知道 Scala 可以调用 Java 函数,但是这段代码不会编译,因为 Java 的函数不是高阶的,所以它对我来说不可用:

val op =
  if (input == "or") java.lang.Boolean.logicalOr
  else java.lang.Boolean.logicalAnd

[1]https://docs.oracle.com/javase/8/docs/api/java/lang/Boolean.html

【问题讨论】:

    标签: scala


    【解决方案1】:

    你可以只使用函数字面量:

    val op: (Boolean, Boolean) => Boolean =
      if (input == "or")
        _ || _
      else
        _ && _
    

    【讨论】:

      【解决方案2】:

      事实

      val op =
        if (input == "or") java.lang.Boolean.logicalOr
        else java.lang.Boolean.logicalAnd
      

      不编译与那些在 Java 或 Scala 中定义的方法无关。

      您发布的代码实际上是在 Scala 3 中编译的。在 Scala 2 中,当您想将方法转换为函数值时,您必须明确:

      val op =
        if (input == "or") java.lang.Boolean.logicalOr _
        else java.lang.Boolean.logicalAnd _
      

      【讨论】:

      • 明确表示您希望 op 成为 (Boolean, Boolean) => Boolean 也可以:val op: (Boolean, Boolean) => Boolean = if (input == "or") java.lang.Boolean.logicalOr else java.lang.Boolean.logicalAnd
      • 是的,如果预期类型是函数类型,则不需要显式转换方法。但在那种情况下,我肯定会选择_ && _ 而不是Boolean.logicalAnd
      【解决方案3】:

      在 Scala 中,您可以避免在 lambda 处理中使用这些方法,使用 _ 语法和位运算符:

      • 布尔值::logicalAnd => _ & _
      • 布尔::逻辑或 => _ | _

      例如,如果你在 Java 中有这样的东西:

      Stream.of(/* .. some objects .. */)
            .map(/* some function that returns a boolean */)
            .reduce(Boolean::logicalOr);
      

      在 Scala 中可以使用_ 语法编写:

      LazyList.fill(/* ... */)
           .map(/* ... */)
           .reduce(_ & _) // or | or ^
      
      

      【讨论】:

      • Java 替代方案不够好。例如,这不会编译:val op = if (input == "or") java.lang.Boolean.logicalOr else java.lang.Boolean.logicalAnd,因为 Java 的函数不是高阶函数。我会更新问题
      • 哦,对了,我很抱歉 :) 你同意我的第二部分吗?我会说你可以毫无问题地使用按位运算符,不是吗?
      • @gianlucaaguzzi 位运算符将在这里工作,因为两个函数参数都将在运算符工作之前进行评估,但除此之外,通常最好使用短路 &&|| .
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      • 2016-05-24
      • 1970-01-01
      • 1970-01-01
      • 2019-01-03
      • 2021-11-09
      相关资源
      最近更新 更多