为什么 Tcl expr 不等于 2 个真布尔值?

Why Tcl expr does not equal 2 true boolean values?

我有这个脚本:

$ cat tmp/bool.tcl
puts "[expr [expr True] == [expr true] ]"

我希望它打印 1 因为 "True" 和 "true" 都是布尔值 true 所以它们应该相等,但我得到 0:

$ tclsh tmp/bool.tcl
0

当然这是简化的代码。真正的代码在字符串中生成布尔值,"True"、"true"、"Yes"、"yEs"等

在比较它们之前是否必须将它们全部设为小写?

我不明白为什么上面的代码不相等。

% puts "[expr [expr True] == [expr true] ]"
0

让我们看看双方做了什么:

% expr True
True
% expr true
true

因此,两者都被识别为布尔值,但并不相等。让我们将这些字符串转换为 "canonical" 布尔形式:

% set a True
True
% set b true
true
% expr {$a == $b}
0
% expr {!!$a == !!$b}
1

这里发生了什么:一步一步

% expr {$a}
True
% expr {!$a}
0
% expr {!!$a}
1

原生 "true/false" 值分别为“1/0”。显然 1 == 1

观点:这感觉像是回到了 Tcl 的 "everything is a string" 根源,字符串 "True" 和 "true" 是不相等的。

== operator定义要做的(expr页面本身的文档比较晦涩):

numeric comparison if possible, exact string comparison otherwise

Truetrue 都不是数字,因此使用精确的字符串比较。这两个值在字符串表示的第一个字符上有所不同;因此,它们在 ==.

的意义上不相等

要比较不受控制的布尔值是否相等,首先将它们取反,因为 ! 运算符的结果既是布尔值又是数字(即,它是 0 或 1):

set a Yes
set b tRuE
expr {!$a == !$b}