4

为什么这不像我想的那样工作?

set x [if {1} {return 2} {return 3}]

命令输出显示2,但是查看 的值x,发现是未定义的..!

我已经阅读了解决方法,...

proc give {x} {return $x}
set x [if {1} {give 2} {give 3}]

...但我不明白为什么第一个不起作用。

来自tcl 8.5 文档if

“命令的返回值是执行的正文脚本的结果,或者如果没有表达式非零且没有 bodyN,则为空字符串。”

问题:

  1. 为什么不set x [if {1} {return 2} {return 3}]设置值x
  2. 鉴于这set x [if {1} {return 2} {return 3}]不起作用,如何在交互式外壳上tclsh显示“ 2”?
  3. 鉴于在交互式外壳上tclsh显示“ ”,它是如何保持未定义的?2set x
4

3 回答 3

7

expr命令返回一个值,因此

set x [if 1 {expr 2} {expr 3}]

但如果你这样做,你不妨使用三元运算符

set x [expr {1 ? 2 : 3}]
于 2013-07-22T01:19:23.670 回答
7

http://www.tcl.tk/man/tcl8.6/TclCmd/return.htm

Tcl 中使用返回码来控制程序流程。Tcl 脚本是一系列 Tcl 命令。只要每个命令评估返回TCL_OK的返回码,评估将继续到脚本中的下一个命令。命令评估返回的任何异常返回代码(非TCL_OK)都会导致流向下一个命令的流程被中断。脚本评估停止,命令的异常返回码成为完整脚本评估的返回码。这是脚本评估期间的错误导致调用堆栈中断和展开的机制。它也是breakcontinuereturn等命令的机制导致脚本评估终止而不按顺序评估所有命令。

因此脚本的评估被中止,x没有被设置,并2作为结果返回并打印。

于 2013-07-21T23:06:46.970 回答
2

set x [if {1} {return 2} {return 3}]正如已经指出的那样,无法按您期望的方式工作的原因是,这return是一个导致脚本评估终止的命令。使用过程的“解决方法”give演示了这样一个事实,即默认情况下,该return命令会终止调用堆栈的 1 级。

然而,“变通方法”实际上是一种毫无意义的自虐练习:该命令允许您使用Tcl 8.5 中引入return的选项指定返回到哪里。-level试试这个,看看它是如何为你工作的。

set x [if {1} {return -level 0 2} {return -level 0 3}]
于 2013-07-25T22:26:03.637 回答