8

首先,我来自 C、Java、Python 背景。'0'最近,我开始为我的新工作学习 Perl,我对(0-string) 是否为假感到好奇。

我已经读到这种特殊行为是 Perl 必须使用<>操作符来读取文件的原因,所以对我来说,这更像是一个设计缺陷,而不是现在的任何事情。但是,我也知道 Perl 是一种成熟的语言,我猜这种行为有它的用途,否则它早就被修复了。

那么在什么情况下'0'= false 会有用呢?

4

6 回答 6

11

如果您读到它与 有任何关系<>,那么您正在阅读不良来源;我无法想象这种说法会从何而来。

'0' 是假的,因为几乎所有地方 perl 都不区分以数字形式存储的数字和以字符串形式存储的数字;在布尔测试中这样做会违背这个原则。

在 '0' 为真的语言(Python、Javascript?)中,我发现 '' 为假很奇怪;为什么要为一个字符串而不是另一个字符串例外?

于 2013-01-09T01:48:41.240 回答
10

Perl 没有显式类型,它对类型的解释高度依赖于上下文。例如:

$a = "2b";
$b = "3a";
$c = $a + $b;
print $c;

产量 5。

另一方面...

$a = "b2";
$b = "3a";
$c = $a + $b;
print $c;

产量 3。

和...

$a = "b2";
$b = "3a";
$c = $a.$b;
print $c;

产量 b23a

所以“'0'(字符串)”不是字符串、数字或布尔值,直到你使用它,然后它可以是任何这些东西,由它的用途决定。直到您尝试操作才确定类型。然后 Perl 评估上下文以努力实现您的意图并采取相应的行动。这是一个特性,以及为什么在 Perl 中有很多方法可以做事。它当然会导致大量令人困惑的代码,但非常适合 1-liners、混淆和 Perl 高尔夫。

于 2013-01-09T01:49:16.090 回答
7

Perl窃取了许多其他语言的特性,包括 C、awk、Bourne shell 和许多其他语言。

在 C 中,任何 0 值都是假的,任何非零值都是真。Perl 只是使用相同的语义。

Perl 比 C 有更多可以在标量或布尔上下文中使用的东西,尤其是字符串,这一事实意味着 Perl 有多个假值。

使整数为0假对 C 程序员来说非常有意义。将空字符串""设为 false 也很有意义。由于 Perl 可以将相同的标量视为数字或字符串,因此使字符串"0"为假几乎是不可避免的。

例如:

$x = 2;
$x -= 2;
print "x = $x\n"; # prints "x = 0"
if ($x) {
    print "A C programmer would be surprised to see this\n";
}

$x = "";
$x .= chr(48);
# Now $x eq "0", a string value that was built without reference to
# the number zero -- but it's nearly the same thing as the number 0.
print "\$x = $x\n"; # pritn "x = 0"
if ($x) {
    print "A C programmer would be equally surprised to see this\n";
}

如果 Perl 是从零开始设计的,没有从其他语言中借用这么多特性,那么它可能会在字符串和数字之间做出更强烈的区分,而不是将它们作为标量组合在一起。给定这样一种假设的类 Perl 语言,空字符串和数字很可能0为假,但字符串"0"为真——您需要显式转换才能将数字转换为0字符串"0"

但是 Perl 就是这样。

于 2013-01-09T01:48:05.360 回答
7

理想情况下,内部存储格式在 Perl 中并不重要。零就是零,不管是存储在IV、UV、NV、PV等中。

事实上,因为它可以,Perl 将改变存储值的格式,这可能会让您感到惊讶。如果字符串0为真,以下将打印“真”:

$x = 0;
print("$x\n");
if ($x) {
   print("true\n");
} else {
   print("false\n");
}
于 2013-01-09T01:56:53.120 回答
2

Perl 有许多被认为是“假”的值:undef、零、字符串"0"、空字符串、一个特殊的布尔值,它根据上下文变形为空字符串或空列表,以及为布尔上下文重载的对象。

其中大部分(undef、零、空字符串、特殊值、对象)实际上非常有用。字符串"0"为假源于 perl 实现标量和假的方式:标量包含字符串部分和数字部分。为了确定,如果一个值是假的,首先查询字符串部分。为什么这是必要的?

my $false_ish = 0;  # the scalar contains only a number
'' . $false_ish;    # force stringy context. the scalar now contains stringy portion.
if ($false_ish) { ... } # string portion is consulted first...

没有这个,一旦你在需要字符串的地方使用数字零,它就会失去它的虚假性。另一方面,这允许"0 but true",一个真正的字符串,它是数字零,并且"0E0",它是零的科学记数法,但也计算为真。

于 2013-01-09T01:51:51.707 回答
0

0 在 C 中也等同于 false - 它在几种“传统”编程语言中等同于 false,这可能是由于 0 与二进制和电路的内在联系,其中 0 可能表示“不收费”。

无论如何,较新的语言通常会继承以前语言的行为和解释。0 是“不收费”或“有收费是假的”的二进制含义早已从任何高级编程语言中抽象出来,但即使通过最现代的编程语言,语义的花絮仍然存在。

另外 - 据我所知,它与 <> 无关 - 你在哪里读到的?

于 2013-01-09T16:06:03.487 回答