TCL / TK:在条件语句中返回vs中断?

时间:2018-10-23 17:32:48

标签: loops tcl

我正在努力思考为什么我的下面带有第一个条件语句中的return的代码会干净地退出,但是当我使用break时出现错误invoked "break" outside of a loop 。有人可以向我解释吗?我的理解是break将退出条件,而return将仅返回一个值,然后退出到主体,并且Tcl解释器将继续评估代码。我的愿望是,如果arg1小于arg2则退出代码,而不评估剩余的arg3语句。我以为我可以用第一个代码块来做到这一点。但是,令我惊讶的是,第二个代码块这样做了却没有继续评估arg3。

这段带有break的代码给了我上述错误:

proc myfunction {arg1 arg2} {
   if {$arg1 < $arg2} {
      puts "$arg1 too low"
      break
   } elseif {$arg1 >= $arg2} {
      puts "Cool beans!"
   }
   set arg3 [expr {$arg1 + $arg2}]
   return $arg3
}

带有return的代码完全退出:

proc myfunction {arg1 arg2} {
   if {$arg1 < $arg2} {
      return [puts "$arg1 too low"]
   } elseif {$arg1 >= $arg2} {
      puts "Cool beans!"
   }
   set arg3 [expr {$arg1 + $arg2}]
   return $arg3
}

1 个答案:

答案 0 :(得分:1)

breakreturn都生成特殊的内部异常类型。然后,它们从生成它们的地方流到处理它们的东西,(在此讨论中)是过程外壳(制造堆栈框架,将实际参数映射到形式参数并在调用后整理)的东西。像forwhile这样的循环结构。

return击中过程外壳时,它将转换为过程的正常结果,而其有效载荷值就是过程的结果。传统上,循环会忽略return并让其循环(从技术上讲,它们可能会进行一些内部清理,尤其是使用foreach时,但您看不到)。您可以传递其他选项以使return有效负载执行其他操作,但是在这里它们并不重要。

break遇到循环时,它将终止循环。当它碰到过程包时,它会转换为错误,您已经看到了错误,表明过程中存在一个break百搭,这通常表示代码有误。


其他主要的异常处理类与catchtry以及用于处理所有异常的顶级处理程序相关。

还有另外两个主要的异常类别:error,这是所有错误的所在,并包含诸如堆栈跟踪之类的附加信息;以及continue,它使循环构造继续到下一个迭代。

Tcl的字节码编译器试图将breakcontinue异常转换为内部跳转,以消除对正确下一阶段处理的使用,从而消除它们的大多数使用。它并不是100%成功的,但是与非疯狂的代码甚至是相当疯狂的代码都非常接近。它还消除了return最常见的情况。