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

TCL use "eq" or "==" when the argument can be a list or a string

提问人:Lumpi 提问时间:7/17/2013 更新时间:7/17/2013 访问量:17509

问:

我有以下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”,因为列表是一种字符串。ARQ

字符串 比较 tcl

评论


答:

11赞 Donal Fellows 7/17/2013 #1

你似乎在那里有点泡菜。首先,您可能不想在条件内使用,因此这就足够了:exprif

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

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

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


您想要在内部使用的一次是在动态选择运算符时。这并不是真的建议这样做,但你会这样做:exprif

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

这很丑陋。(请注意,我把其他所有东西都放在它自己的大括号里,以防止重复计算,而且我小心翼翼地正确平衡所有括号,这就是你在问题的代码中绊倒你的原因。除非你真的需要,否则不要这样做。

评论

0赞 Donal Fellows 7/17/2013
此外,并且是数字(尽管后者可能很快就会成为检查错误;NaN是奇怪的东西)根据Tcl和IEEE浮点运算。InfNaN
0赞 ted 2/16/2019
你为什么要用不会稍微不那么丑?还是有理由不惜一切代价坚持使用卷曲的牙套?if { [expr {$Node_3} $op {"BadAngle"} ]}if "\$Node_3 $op {BadAngle}"
5赞 kostix 7/17/2013 #2

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

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

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

    现在,机器看到一个光秃秃的词“expr”,却不知道该怎么处理它。

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

    • 错误的方式 — 正确调用:expr

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

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

    • 正确的方法 — 只需放弃不需要的:expr

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

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

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

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