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

Lum*_*mpi 6 string compare tcl

我有以下if循环:

if { expr { $Node_3 eq "BadAngle" } } {
  return "BadAngle"
}
Run Code Online (Sandbox Code Playgroud)

Node_3可以是包含坐标的列表,也可以是简单的字符串"BadAngle",我使用TCLPro 1.4进行调试和TCL 8.6.我明白了:

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

然后我也尝试过:

if { [ expr { $Node_3 eq "BadAngle" ] == 1 } } {
   return "BadAngle"
}
Run Code Online (Sandbox Code Playgroud)

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

Don*_*ows 8

你似乎在那里遇到了一点点腌渍.首先,你可能不想exprif条件内部使用,所以这就足够了:

if { $Node_3 eq "BadAngle" } {
    return "BadAngle"
}
Run Code Online (Sandbox Code Playgroud)

由于你要比较的东西之一肯定是非数字的,你可以使用eq运算符,尽管==运算符是等价的.唯一不同的是,当两个操作数看起来像数字时,何时==将它们作为数字进行比较(如果需要,将它们分解为数字).这意味着"1" == "0x01"尽管它们是相当不同的字符串; 该eq运营商总是比较为字符串.

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


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

set op "=="
if { [expr {$Node_3} $op {"BadAngle"} ]} {
    return "BadAngle"
}
Run Code Online (Sandbox Code Playgroud)

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


kos*_*tix 5

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

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

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

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

    修复代码有两种方法:

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

    if { [ expr { $Node_3 eq "BadAngle" } ] == 1 } } { ... }
    
    Run Code Online (Sandbox Code Playgroud)

在任何情况下,正确的解决方案是简单地使用

if {$Node_3 eq "BadAngle"} { ... }
Run Code Online (Sandbox Code Playgroud)