如何在Tcl中将字符串转换/强制转换为布尔值?

4

I was expecting

if {[some_func $some_args]} {
   ....
}

希望当 some_func 返回某个字符串时,整个表达式能够被求值为真且正常工作。然而出现了错误。

通常情况下,Tcl 只接受以下几种值:

  • 空字符串 -> 假(False)
  • 0 -> 假(False)
  • false -> 假(False)
  • true -> 真(True)
  • 1 -> 真(True)

更加精确的说:

% expr 1
1
% expr 0
0
% expr
wrong # args: should be "expr arg ?arg ...?"
% expr {{}}
% expr true
true
% expr false
false
% expr True
syntax error in expression "True": variable references require preceding $
% expr False
syntax error in expression "False": variable references require preceding $

看起来expr不会将返回值规范化。特别注意,如果给定空字符串,则结果为空字符串。

那么我如何轻松地将字符串转换为布尔值?


严格来说,有一小部分字符串被认为是可解释为布尔值的;其他可能性则不是。如果这还不够,我只会鼓励思考你真正想表达的意思;你真正想要什么样的测试? - Donal Fellows
2个回答

3

经过一番思考和调查,答案可能是:"这取决于情况"

由于我有Perl编程背景,所以我期望 Tcl 也有类似的语法。但这是我的错。

在Tcl中,string is true似乎是官方的转换函数。可以用以下链接中定义的字符串进行转换:这里

如果字符串是0、false、no或off中的任何一个,则Tcl_GetBoolean在* boolPtr处存储零值。 如果字符串是1、true、yes或on中的任何一个,则将1存储在* boolPtr处。 这些值都可以缩写,并且大写拼写也可接受。

在我的情况下,我不关心字符串的内容,因此可以直接

if {[string length [some_func $some_args]] > 0} {
  ...
}

另一种更简单的写法是这样的:
if {[some_func $some_args] != {}} {
  ...
}

是的,这是正确的答案。自8.4以来,您还可以编写if {[some_func $some_args] ne ""},这样会少一些花括号。 - kostix
2
我还要指出,我认为 Tcl 处理布尔值的方式比 Perl 和 PHP 更合理,后者存在愚蠢的类型转换。在这方面,Tcl 的唯一失误是可怕的八进制问题,我们希望在 9.0 中能够解决它 ;-) - kostix
1
@kostix: +1 Ceterum censeo octal numeros esse delendam. - Donal Fellows

2

从用户的角度来看,Tcl 没有将一个类型的值转换为另一种类型的能力或需要。相反,所有的值都是字符串,并且您需要问:“可以将这个值解释为?”。例如:

set value 1
string is boolean $value
> 1
string is integer $value
> 1

set value true
string is boolean $value
> 1
string is integer $value
> 0

还有一些[string is]子命令,用于检查特定值,但这主要是为了方便。例如:

string is true $value
# effectively equivalent to
expr {[string is boolean $value] && $value}  

因此,话虽如此,随着时间的推移,可以解释为真实的字符串也有所变化,如果我没记错的话。我的建议是始终使用“true”或“false”,因为所有版本的Tcl(我想)都将它们识别为布尔值,并且它们准确地表示了其作为布尔值的意图(我认为1/0不行)。

如果您真正想做的是查找是否存在实际内容的字符串,则只需使用:

if {[string length $value] > 0} { ....}

如果你想模拟其他语言的真实性版本,那么我的建议是不要这样做。当然,你可以通过 实现。
if { (![string is false $value]) && [string length $value] > 0 } { ... }

但这可能不是正确的方法。

在底层,Tcl实际上执行了所有的类型转换。然而,这被认为是实现的特性,而不是语言的特性;Tcl语言是无类型的。 - Donal Fellows
因此短语“从用户的角度来看” :) - RHSeeger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接