1
% 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

4 回答 4

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 "

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

" 1 == 1 "

但它又是字符串

为什么 Tcl 抱怨?正如它所说,您正在尝试使用非数字字符串作为 的操作数&&,并且{ $HI == 1 }不是数字,因为无法将其视为数字,因此 Tcl 无法根据数字转换为真/假值(如果为 0,则为 false,如果不为 0,则为 true),并且发生错误。

我想你真正想写的是

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

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

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

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。

于 2012-11-09T08:51:09.567 回答
5

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

if { [info exists HI] && $HI == 1 } { puts "Hello World" }
于 2012-11-08T23:05:28.930 回答
1

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

于 2012-11-08T23:05:51.990 回答
1

在 Tcl 表达式中,{…<code>} 包含一个未替换的文字。(或者如果之前有一个变量名$。)当你有一个表达式时,这表明你应该执行以下任一操作:

  • {将...<code>}更改为(...<code>); 括号在表达式中具有其正常的数学解释。
  • {将...<code>}更改为... [expr {<code>}] 以便表达式真正被解释为这样。

这两种情况的字节码几乎是相同的,所以在性能方面它是一个洗牌。你应该写哪个对你来说更清楚。(我自己,我几乎从不使用第二种形式,[expr]在我想要一个非常量表达式片段的情况下在表达式上下文中保留嵌套。这实际上非常罕见。)

于 2012-11-09T09:29:34.330 回答