Scala,方法调用用点编译,没有编译

时间:2014-04-22 05:36:14

标签: scala

出于自我折磨的目的,我一直在尝试编写自己的if-elseif-else构造实现(when-butWhen-otherwise在我的案例中)。有趣的是,我写的东西在butWhen之前没有一个点编译,并且用它编译,并且在otherwise之前编译有和没有点的情况:

    when(false) {
      println(">> True")
    }.butWhen(false) {
      println(">> hello")
    }.butWhen(false) { // Without the dot says "Boolean(false) does not take parameters"
      println(">> Goodbye")
    } otherwise {
      println(">> Something else")
    }

对于我未经训练的眼睛,butWhen和其他方面的声明是相同的,它们返回相同的东西,所以看起来它们必须表现相同。此外,当我将otherwise直接链接到when子句时,编译成功也没有点。

你可以帮我摆脱点吗?以下是when-butWhen-otherwise的代码:

trait ButWhenTrait {
  def butWhen(b: Boolean)(op3: => Unit): ButWhenTrait
  def otherwise(op2: => Unit) // {}
}

object when { def apply(b: Boolean)(op: => Unit): ButWhenTrait = { if (b) { op DeadEnd } else FalseWhen } }

object FalseWhen extends ButWhenTrait { override def otherwise(op2: => Unit) { op2 } override def butWhen(b: Boolean)(op2: => Unit) = { if (b) { op2 DeadEnd } else { FalseWhen } } }

object DeadEnd extends ButWhenTrait { override def otherwise(op: => Unit) {} override def butWhen(b: Boolean)(op: => Unit) = { DeadEnd } }

1 个答案:

答案 0 :(得分:5)

由下一个限制引起的错误:Method Invocation的后缀表示法仅适用于 Arity-0 & Arity-1 方法。

可能的解决方案:

1)通过将调用拆分为2个对象来减少方法arity:

- 更新(错误修正) -

trait ButWhenTrait {
  def butWhen(b: Boolean): ExecBlock
  def otherwise(op: => Unit): Unit
}

trait ExecBlock {
  // $ name of method for transfer execution function
  def $(op : => Unit): ButWhenTrait
}

object NextExecBlock extends ExecBlock {
  object next extends ButWhenTrait {
    def butWhen(b: Boolean): ExecBlock = if(b) EndExecBlock else NextExecBlock
    def otherwise(op: => Unit) { op }
  }
  def $(op : => Unit): ButWhenTrait = next
}

trait EmptyButWhenTrait {
  object next extends ButWhenTrait {
    def otherwise(op : => Unit) {}
    def butWhen(b : Boolean) = EmptyExecBlock
  }
}

object EndExecBlock extends ExecBlock with EmptyButWhenTrait {
  def $(op : => Unit): ButWhenTrait = { op; next }
}

object EmptyExecBlock extends ExecBlock with EmptyButWhenTrait {
  def $(op : => Unit): ButWhenTrait = next
}

object when {
  def apply(b: Boolean)(op: => Unit): ButWhenTrait =
    if(b) EndExecBlock $ op else NextExecBlock $ op
} 

比用法:

when(false) {
  println(">> True")
} butWhen(false) $ {
  println(">> hello")
} butWhen(false) $ {
  println(">> Goodbye")
} otherwise {
  println(">> Something else")
}

2)使用apply方法对boolean to object进行隐式对比:

trait ButWhenTrait {
  def butWhen(op :  ButWhenTrait): ButWhenTrait = op
  def otherwise(op: => Unit) { op }
}

class ExecBlock(b : Boolean) {
  private object next extends ButWhenTrait
  private object end extends ButWhenTrait {
    override def butWhen(op : ButWhenTrait) = end
    override def otherwise(op : => Unit) {}
  }

  def apply(op : => Unit): ButWhenTrait = if(b) { op; end } else next
}

object when {
  def apply(b: Boolean)(op: => Unit): ButWhenTrait = new ExecBlock(b)(op)
} 

// AND implicit conversion:
implicit def boolToExec(b : Boolean): ExecBlock = new ExecBlock(b) 

比用法(如你所料):

when(false) {
  println(">> True")
} butWhen(false) {
  println(">> hello")
} butWhen(false) {
  println(">> Goodbye")
} otherwise {
  println(">> Something else")
}