【问题标题】:Custom control structure with two blocks具有两个块的自定义控制结构
【发布时间】:2015-01-10 07:57:07
【问题描述】:

我是 Scala 的新手,在阅读一些教程和文档时,我尝试定义自定义控制结构。

所以我尝试实现一个隐式类MyBoolean,它提供了一个带有两个参数列表的? 方法。第一个参数是在MyBoolean 为真时执行的块,第二个在MyBoolean 为假时执行。

以下是生成的控制结构的语法示例:

true ? {println("true")} {println("false")};

所以本质上只是一个简单的 if-else 语句,作为布尔方法实现。

这是我的实现:

object Test extends App {
    implicit class MyBoolean(val value: Boolean) {
        def ? (body1: => Unit)(body2: => Unit){
            if (value) body1;
            else body2
        }
    }

    override def main(args: Array[String]): Unit = {
//      true ? {println("true")} {println("false")}; //--> compiler error
      true.? {println("true")} {println("false")}; // works fine...
    }
}

我面临的问题是使用预期的语法(在 Eclipse 中)出现以下编译器错误:

方法缺少参数?在 MyBoolean 类中;按照这个方法 如果您想将其视为部分应用的函数,请使用 `_'

仅当我在方法 ? 之前显式添加点 . 时才有效。

在调用方法时,点在 Scala 中不应该是可选的吗?我有什么遗漏吗?

【问题讨论】:

    标签: scala


    【解决方案1】:

    在Scala中调用方法时点不应该是可选的吗?

    有点,但这并不完全准确。

    在这些情况下,确实如此:

    • a.b(c) 可以写成a b c
    • a.b(c, d) 可以改写为a b (c, d)

    来自language spec 部分 6.12.3,中缀操作:

    左结合运算符的右手操作数可以由括号中的几个参数组成,例如e op e1, ..., en。这个表达式被解释为 e.op(e1, ..., en)

    左关联二元运算 e1 op e2 被解释为 e1 .op(e2).

    但是对于a.b(c)(d) 形式的表达式没有相应的规则。不过,我不确定为什么。在我看来,a b {c} {d} 是一种非常合理的写法。

    【讨论】:

      【解决方案2】:

      这是 Scala 语法中最奇怪的问题之一。您仍然可以对多个参数列表使用无点样式,但您必须使用括号对对象、方法和第一个参数列表进行分组 (?!)

      (true ? {println("true")}) {println("false")}
      

      工作得很好。

      为什么会这样?使用/::\ 折叠符号相当方便;然后你可以将你的第一个元素与它应该运行的集合组合在一起。

      对于其他一切,充其量是值得怀疑的。

      无论如何,您都被括号或点卡住了。

      【讨论】:

        【解决方案3】:

        点在调用 1-parameter 方法时是可选的,但该语法不适用于 2-parameter 方法,即使在 curried 时也是如此(除非@RexKerr 建议将其括起来)。

        你也许可以通过“手动”柯里化来让它工作:编写一个单参数方法,返回一个带有 apply 的对象:

        class PartiallyApplied(value: Boolean, body1: => Unit) {
          def apply(body2: => Unit) = if (value) body1; else body2
        }
        
        class MyBoolean...
          def ? (body1: => Unit) = new PartiallyApplied(value, body1)
        

        【讨论】:

        • 我尝试了您的建议,但它导致了同样的问题 - 即在方法之前必须仍然在点处。无论如何:+1 否则正确答案。
        猜你喜欢
        • 1970-01-01
        • 2011-04-04
        • 1970-01-01
        • 2013-05-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-09
        相关资源
        最近更新 更多