TCL:if语句中如何发生替换

TCL:if语句中如何发生替换,tcl,Tcl,考虑以下代码,其中a是一个全局变量: % set a 1 1 % # FirstCase % if "$a==1" " puts >>>>>>>>>>>>>>>> " >>>>>>>>>>>>>>>> % # Second case % if {$a==1} { puts >

考虑以下代码,其中
a
是一个全局变量:

% set a 1
1
% # FirstCase 
% if "$a==1" "
       puts >>>>>>>>>>>>>>>>
"
>>>>>>>>>>>>>>>>
% # Second case
% if {$a==1} {
     puts >>>>>>>>>>>>>>>>
}
>>>>>>>>>>>>>>>>
在我的第一个例子中,我用
做了一个
if
语句。因此,将在此处替换
a
。可以接受


在第二个例子中,我用
{}
做了一个
if
语句。
a
的替换是如何发生的
{}
表示不替换,但仍使用变量。在
if
相关代码中,它是否查找变量
a
的全局堆栈?

if命令,如
expr
被设计为显式替换给定给它的参数。使用
分组是不可取的,因为它可能会导致出现双重替换

与tcl中的其他命令一样,
if
实际上是一个函数。它不查看全局堆栈,而是计算调用方堆栈中的表达式

实际上,您可以使用uplevel编写自己版本的if:

proc _if_ {expression script} {
    # uplevel causes expr to be evaluated in the caller's stack:
    set condition [uplevel 1 "expr {$expression}"]

    if {$condition} {
        uplevel 1 $script
    }
}
在第一种情况下:“$a==1”是一个字符串,而不是零值,这将使它成为真:Try->

% if "0" "
 puts >>>>>>>>>>>>>>>>
"
它不会通过该条件。您在这里很幸运,因为“$a==1”的值不是零,并且传递给if的值变为true

在第二种情况下:

% if {$a==1} {
    puts >>>>>>>>>>>>>>>>
}

$a==1->本身就是一个条件。

对不起,但是int tcl字符串“0”和值0之间没有区别。你的理解是错误的。在调用
if
之前,字符串“$a==1”被替换为“1==1”。字符串“1==1”的计算结果为true(技术上为1),因此执行put。在第二种情况下,字符串“\$a==1”直接传入,如果
if
,则在调用堆栈中对其求值,调用堆栈可以访问$a,因此它也会求值为true,并执行put。两种方法都有效,他的问题是为什么?我的意思完全一样。“$a==1”被视为一个字符串,将对其求值,然后返回结果1或0。感谢@slebetman为我澄清。返回的结果1或0也是字符串