6

我有以下 if 循环:

if { expr { $Node_3 eq "BadAngle" } } {
  return "BadAngle"
}

Node_3 可以是一个包含坐标的列表,也可以是简单的字符串“BadAngle”,我使用 TCLPro 1.4 和 TCL 8.6 进行调试。我得到:

*表达式 "expr { $Node_3 eq "BadAngle" } "* 中的语法错误

然后我也尝试了:

if { [ expr { $Node_3 eq "BadAngle" ] == 1 } } {
   return "BadAngle"
}

但我得到同样的错误。另外:在这种情况下,更好的选择是什么:要使用“==”或“eq”,我认为“eq”是因为列表是一种字符串..or?

4

2 回答 2

9

你好像有点吃不消了。首先,您可能不想expr在条件内部使用if,所以这就足够了:

if { $Node_3 eq "BadAngle" } {
    return "BadAngle"
}

由于您要比较的事物之一肯定是非数字的,因此eq尽管==运算符是等效的,但使用运算符会很好。唯一不同的是当两个操作数看起来像数字时,何时==将它们作为数字进行比较(如果需要,将它们解析为数字)。这意味着"1" == "0x01"尽管它们是相当不同的字符串;运算符eq始终作为字符串进行比较。

如何选择最好的?这实际上很简单:你认为你现在在比较的两边都使用数字吗?如果是,则使用==,否则使用eq


您想在expr内部使用的一次if是当您动态选择运算符时。这不是真的推荐,但你会这样做:

set op "=="
if { [expr {$Node_3} $op {"BadAngle"} ]} {
    return "BadAngle"
}

这很丑陋。(请注意,我将其他所有内容都放在自己的大括号中以防止重复评估,并且我会小心地正确平衡所有括号,这就是在您的问题代码中绊倒您的原因。)除非您这样做,否则不要这样做真的需要。

于 2013-07-17T10:22:25.993 回答
3

您的尝试中有两个明显的问题:

  1. 在第一个示例中,您尝试以expr错误的方式调用:(if以及支持条件的其他命令,例如while)使用相同的机制来评估expr命令执行的条件 - 引用手册

    if 命令将 expr1 评估为表达式(与 expr 评估其参数的方式相同)。

    现在机器只看到一个单词“expr”并且不知道如何处理它。

    有两种方法可以修复代码:

    • 错误的方式 - 正确调用expr

       if {[expr {$Node_3 eq "BadAngle"}]} { ... }
      

      这是错误的,因为嵌套调用expr纯粹是肤浅的。

    • 正确的方法 - 只需丢弃不需要的expr

       if {$Node_3 eq "BadAngle"} { ... }
      
  2. 在第二个示例中,您决定通过引入另一个布尔测试来使情况更加复杂(不需要,因为eqand==运算符已经返回布尔类型的值)。但是在这种情况下,您忘记放置执行分组的右大括号,}因为代码应该是

    if { [ expr { $Node_3 eq "BadAngle" } ] == 1 } } { ... }
    

无论如何,正确的解决方案是简单地使用

if {$Node_3 eq "BadAngle"} { ... }
于 2013-07-17T10:23:18.820 回答