我有以下代码,但我无法让它工作.一旦我在表壳内放置一个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,则返回
你希望这个循环返回哪个迭代?如果您想要Seq所有迭代的结果,请使用for表达式(也称为for理解).如果你只想要最后一个,var在循环外创建一个,在每次迭代时设置它的值,并var在循环之后返回它.(另请参阅其他循环结构,这些结构在不同类型的集合中实现为函数,例如foldLeft和foldRight,就返回值而言,它们有自己有趣的行为.)Scala while循环返回,Unit因为没有合理的一个大小适合所有答案题.
(顺便说一句,编译器无法知道这一点,但你编写的循环永远不会返回.如果编译器理论上足够聪明,可以判断while(true)永远不会终止,那么预期的返回类型就是Nothing.)
从其他答案中可以清楚地看到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)
(请注意,我并未声明该构造有用.)
while循环的唯一目的是执行副作用.换句话说,它总会评估为单位.
如果你想要一些有意义的东西,为什么不考虑使用if-else-expression或for-expression?
| 归档时间: |
|
| 查看次数: |
3756 次 |
| 最近记录: |