如何使测试条件在TCL中工作

时间:2012-11-08 22:51:18

标签: string tcl

% set HI 1
1
% if { [ info exists HI] && { $HI == 1 } } { puts "Hello World "}
can't use non-numeric string as operand of "&&"
%   

任何一种情况都可以单独测试。如何制作&&测试工作在TCL?

仅此一项工作

% if  { $HI == 1 }  { puts "Hello World "}
Hello World

这也是独一无二的。

% if { [ info exists HI]  } { puts "Hello World "}
Hello World

4 个答案:

答案 0 :(得分:5)

你不需要额外的花括号;这应该可以正常工作:

if { [info exists HI] && $HI == 1 } { puts "Hello World" }

答案 1 :(得分:5)

测试的第二部分,即

{ $HI == 1 }

是错误的,因为我认为你对Tcl中括号的含义感到困惑。大括号( ... )不相同,它们不能用于数学表达式中以更改评估中使用的优先级。

大括号用于组成包含空格的字符串,并使其显示为Tcl命令的单个参数,但没有在其中执行替换。

在您的情况下,$HI不会替换为HI变量的值,因此您要形成一个字符串,其中包含您在大括号内看到的所有确切字符,包括前导和尾随空格。

如果你这样做

if {{ $HI == 1 } eq {$HI == 1}} {
    puts "same"
} else {
    puts "not the same"
}

结果会得到not the same。 (eq在表达式中执行字符串比较。)

如果你使用双引号字符作为字符串分隔符,那么你不会得到正确的意思,即

" $HI == 1 "

在这种情况下,您的变量实际上已替换为其值,因此就像您直接编写的那样(假设$HI1,如您的代码中所示):

" 1 == 1 "

但它是字符串,再次

为什么Tcl抱怨?正如它所说,你试图使用非数字字符串作为&&的操作数,而{ $HI == 1 } 不是数字,因为没有办法要看是一个数字,所以Tcl不能转换为真/假值,具体取决于数字(如果为0则为false,如果不为0则为true),并且发生错误。

我认为你真正想写的是

if { [ info exists HI] && ( $HI == 1 ) } { puts "Hello World "}
#                         ^          ^
#                         |__________|____ note ( ) instead of { }

==提供&&更高的优先级,或使条件更明确。 expr,在if的测试条件中隐式调用,知道关于圆括号与您在其他编程语言和数学中找到的含义相同:更改评估顺序。

正如在其他答案和评论中已经指出的那样,你真的不需要括号,因为(如在C语言和许多其他语言中),等号运算符==的优先级高于布尔值和&&。但如果您愿意,可以毫不畏惧地使用( ... )

if {2 - 1 * 2} { puts yes } { puts no }

给出no,因为表达式被评估为2 - (1 * 2),即0。

if {(2 - 1) * 2} { puts yes } { puts no }

提供yes因为(2 - 1) * 2为2。

答案 2 :(得分:1)

尝试[expr $HI == 1]代替{ $HI == 1 }

答案 3 :(得分:1)

在Tcl表达式中,{ ... }包含一个未替换的文字。 (如果之前有$,则为变量名。)如果你有一个表达式,那表明你应该做以下任何一个:

  • { ... }更改为( ... );括号在表达式中有正常的数学解释。
  • { ... }更改为[expr { ... }],以便表达式真正解释为此。

两种情况下的字节码实际上是相同的,因此在性能方面它是一种清洗。你应该写出更清楚的东西。 (我自己,我几乎没有使用第二种形式,在表达式上下文中保留嵌套[expr],以便我想要一个非常量表达式片段。这实际上非常罕见。)< / p>