Scala while循环一直返回Unit

San*_*der 2 scala while-loop

我有以下代码,但我无法让它工作.一旦我在表壳内放置一个while循环,它就会返回一个单位,无论我在括号内改变什么.

case While(c, body) =>
    while (true) {
      eval(Num(1))
    }
}
Run Code Online (Sandbox Code Playgroud)

如何使while循环返回非Unit类型?

我尝试在我的条件下添加括号,但它仍然没有按照预期的那样做.

有什么指针吗?

更新

更多的背景信息,因为我没有真正解释代码应该做什么,如果我想得到一些帮助,这似乎很方便;

我已经定义了一个eval(exp : Exp).这将评估一个功能. Exp是一个抽象类.几类,如扩展Plus,Minus(几个基本操作)和IfThenElse(cond : Exp, then : Exp, else : Exp).最后但并非最不重要的是,有While(cond: Exp, body: Exp).

如何使用它的例子;

eval(Plus(Num(1),Num(4))会导致NumValue(5).(Num(v:Value)的评估结果为NumValue(v).NumValue扩展了Value,这是另一个抽象类).

eval(While(Lt(Num(1),Var("n")), Plus(Num(1), Var("n"))))
Run Code Online (Sandbox Code Playgroud)

Lt(a : Exp, b : Exp)NumValue(1)如果<b,则返回

Ken*_*oom 8

你希望这个循环返回哪个迭代?如果您想要Seq所有迭代的结果,请使用for表达式(也称为for理解).如果你只想要最后一个,var在循环外创建一个,在每次迭代时设置它的值,并var在循环之后返回它.(另请参阅其他循环结构,这些结构在不同类型的集合中实现为函数,例如foldLeftfoldRight,就返回值而言,它们有自己有趣的行为.)Scala while循环返回,Unit因为没有合理的一个大小适合所有答案题.

(顺便说一句,编译器无法知道这一点,但你编写的循环永远不会返回.如果编译器理论上足够聪明,可以判断while(true)永远不会终止,那么预期的返回类型就是Nothing.)


Phi*_*ppe 8

从其他答案中可以清楚地看到Scala while循环总是返回Unit.Scala的优点在于,如果它不能满足您的需求,您可以随时扩展它.

这是一个while-like构造的定义,它返回最后一次迭代的结果(如果永远不输入循环,它将抛出异常):

def whiley[T](cond : =>Boolean)(body : =>T) : T = {
  @scala.annotation.tailrec
  def loop(previous : T) : T = if(cond) loop(body) else previous
  if(cond) loop(body) else throw new Exception("Loop must be entered at least once.")
}
Run Code Online (Sandbox Code Playgroud)

...然后你可以用它作为while.(实际上,@tailrec注释会使它编译成与while循环完全相同的东西.)

var x = 10
val atExit = whiley(x > 0) {
  val squared = x * x
  println(x)
  x -= 1
  squared
}
println("The last time x was printed, its square was : " + atExit)
Run Code Online (Sandbox Code Playgroud)

(请注意,我并未声明该构造有用.)


Hei*_*ger 7

while循环的唯一目的是执行副作用.换句话说,它总会评估为单位.

如果你想要一些有意义的东西,为什么不考虑使用if-else-expression或for-expression?