当参数可以是列表或字符串时,TCL使用“eq”或“==”

时间:2013-07-17 09:44:56

标签: string compare tcl

我有以下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”因为列表是一种字符串......或者?

2 个答案:

答案 0 :(得分:8)

你似乎在那里吃了一点腌菜。首先,您可能不想在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"
}

这很难看。 (请注意,我将其他所有内容放在自己的大括号中以防止双重评估,并且我小心地正确平衡所有括号,这就是你在问题中的代码中绊倒你。)不要做它除非你真的真的需要。

答案 1 :(得分:3)

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

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

      

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

    现在机器看到了一个“expr”字样,并且不知道如何处理它。

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

    • 错误的方法 - 正确拨打expr

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

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

    • 正确的方法 - 只需删除不需要的expr

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

    if { [ expr { $Node_3 eq "BadAngle" } ] == 1 } } { ... }
    
  3. 无论如何,正确的解决方案是使用

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