“0但真实”是什么意思? Perl 中的意思是?
有人能解释一下 Perl 中字符串“0 but true”的确切含义吗?据我了解,它在整数比较中等于零,但在用作布尔值时计算结果为 true。这是正确的吗?这是语言的正常行为还是解释器中将其视为特殊情况的特殊字符串?
Can someone explain what exactly the string "0 but true" means in Perl? As far as I understand, it equals zero in an integer comparison, but evaluates to true when used as a boolean. Is this correct? Is this a normal behavior of the language or is this a special string treated as a special case in the interpreter?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
这是语言的正常行为。引用
perlsyn
联机帮助页:因此,需要有一种方法可以从希望返回
0
作为(成功)返回值的系统调用中返回0
,并留出一种方式来发出信号实际上返回错误值的失败案例。“0 but true”
就是为了这个目的。It's normal behaviour of the language. Quoting the
perlsyn
manpage:Because of this, there needs to be a way to return
0
from a system call that expects to return0
as a (successful) return value, and leave a way to signal a failure case by actually returning a false value."0 but true"
serves that purpose.因为它在 Perl 核心中被硬编码为将其视为数字。这是一个让 Perl 的约定和 ioctl 的约定一起发挥作用的 hack;来自perldoc -f ioctl:
Because it's hardcoded in the Perl core to treat it as a number. This is a hack to make Perl's conventions and
ioctl
's conventions play together; fromperldoc -f ioctl
:除了其他人所说的之外,“0 but true”是特殊情况,因为它不会在数字上下文中发出警告:
Additionally to what others said,
"0 but true"
is special-cased in that it doesn't warn in numeric context:值
0 but true
是 Perl 中的一个特殊情况。尽管在普通人看来,它看起来不像一个数字,但明智且无所不知的 Perl 知道它确实是一个数字。它与以下事实有关:当 Perl 子例程返回 0 值时,假定例程失败或返回假值。
想象一下,我有一个返回两个数字之和的子例程:
第一个语句不会终止,因为子例程将返回
1
。那挺好的。第二条语句将终止,因为子例程无法将cow添加到dog。
那么,第三个陈述呢?
嗯,我可以将
3
添加到-3
中。我只得到0
,但是即使add
子例程有效,我的程序也会死掉!为了解决这个问题,Perl 将
0 but true
视为数字。如果我的 add 子例程不仅返回 0,而且返回 0 but true,则我的第三条语句将起作用。但是 0 but true 是数字零吗?试试这些:
是的,它是零!
index 子例程是 Perl 中一个非常古老的部分,在 概念出现之前就已存在0 但 true 就在附近。假设返回子字符串在字符串中的位置:
最后一条语句返回
-1
。这意味着如果我这样做:就像我通常对标准函数所做的那样,它将不起作用。如果我像在第二个语句中那样使用“barfoo”和“bar”,则
else
子句将执行,但如果我像第三个语句中那样使用“barfoo”和“fu”,则>if
子句将执行。不是我想要的。但是,如果
index
子例程对于第二条语句返回 0 but true,对于第三条语句返回undef
,则我的if
/else
子句会起作用。The value
0 but true
is a special case in Perl. Although to your mere mortal eyes, it doesn't look like a number, wise and all knowing Perl understands it really is a number.It has to do with the fact that when a Perl subroutine returns a 0 value, it is assumed that the routine failed or returned a false value.
Imagine I have a subroutine that returns the sum of two numbers:
The first statement won't die because the subroutine will return a
1
. That's good.The second statement will die because the subroutine won't be able to add cow to dog.
And, the third statement?
Hmmm, I can add
3
to-3
. I just get0
, but then my program will die even though theadd
subroutine worked!To get around this, Perl considers
0 but true
to be a number. If my add subroutine returns not merely 0, but 0 but true, my third statement will work.But is 0 but true a numeric zero? Try these:
Yup, it's zero!
The index subroutine is a very old piece of Perl and existed before the concept of 0 but true was around. It is suppose to return the position of the substring located in the string:
The last statment returns a
-1
. Which means if I did this:As I normally do with standard functions, it wouldn't work. If I used "barfoo" and "bar" like I did in the second statement, The
else
clause would execute, but if I used "barfoo" and "fu" as in the third, theif
clause would execute. Not what I want.However, if the
index
subroutine returned 0 but true for the second statement andundef
for the third statement, myif
/else
clause would have worked.您还可能会看到 Perl 代码中使用的字符串"0E0",其含义相同事情,其中 0E0 只是表示以指数表示法书写的 0。然而,由于 Perl 只将“0”、“”或 undef 视为 false,因此它在布尔上下文中计算结果为 true。
You may also see the string "0E0" used in Perl code, and it means the same thing, where 0E0 just means 0 written in exponential notation. However, since Perl only considers "0", '' or undef as false, it evaluates to true in a boolean context.
它是硬编码在 Perl 的源代码中,特别是在 Perl_grok_number_flags 中的 numeric 中.c。
阅读该代码我发现字符串“infinity”(不区分大小写)也通过了looks_like_number 测试。我不知道这一点。
It's hard-coded in Perl's source code, specifically in Perl_grok_number_flags in numeric.c.
Reading that code I discovered that the string "infinity" (case insensitive) passes the looks_like_number test too. I hadn't known that.
在整数上下文中,它的计算结果为 0(字符串开头的数字部分)并且为零。在标量上下文中,它是一个非空值,因此为 true。
if (int("0 但为真")) { print "零"; }
(无输出)
if ("0 but true") { print "true"; }
(打印 true)
In an integer context, it evaluates to 0 (the numeric part at the beginning of the string) and is zero. In a scalar context, it's a non-empty value, so it is true.
if (int("0 but true")) { print "zero"; }
(no output)
if ("0 but true") { print "true"; }
(prints true)
0 在 Perl(以及与 C 相关的其他语言)中表示 false。在大多数情况下,这是一种合理的行为。其他语言(例如 Lua)将 0 视为 true,并提供另一个标记(通常 nil 或 false)来表示非 true 值。
Perl 方法不太有效的一种情况是,您想要返回一个数字,或者如果函数由于某种原因失败,则返回一个假值。例如,如果您编写一个函数从文件中读取一行并返回该行的字符数。该函数的常见用法可能类似于:
请注意,如果特定行上的字符数为 0,则 while 循环将在文件结束之前结束。因此 characters_in_line 函数应该将 0 个字符特殊化并返回 '0 but true'。这样,该函数将在 while 循环中按预期工作,而且如果将其用作数字,也会返回正确的答案。
请注意,这不是该语言的内置部分。相反,它利用 Perl 将字符串解释为数字的能力。所以有时会用其他蜇刺来代替。例如,DBI 使用“0E0”。在数字上下文中计算时,它们返回0,但在布尔上下文中,返回false。
0 means false in Perl (and other languages related to C). For the most part, that's a reasonable behavior. Other languages (Lua for instance) treat 0 as true and provide another token (often nil or false) to represent a non-true value.
One case where the Perl way doesn't work so well is when you want to return either a number or, if the function fails for some reason, a false value. For instance, if you write a function that reads a line from a file and returns the number of characters on the line. A common usage of the function might be something like:
Notice that if the number of characters on a particular line is 0, the while loop will end before the end of the file. So the characters_in_line function should special case 0 characters and return '0 but true' instead. That way the function will work as intended in the while loop, but also return the correct answer should it be used as a number.
Note that this isn't a built in part of the language. Rather it takes advantage of Perl's ability to interpret a string as a number. So other stings are sometimes used instead. DBI uses "0E0", for instance. When evaluated in numeric context, they return 0, but in boolean context, false.
错误的事情:
""
。“0 but true”
不是其中之一,因此它不是 false。此外,Perl 返回“0 but true”,其中需要一个数字,以便表明函数成功,即使它返回零。 sysseek 就是此类函数的一个示例。由于该值预计将用作数字,因此 Perl 编码为将其视为数字。因此,当它用作数字时,不会发出警告,并且
looks_like_number("0 but true")
返回 true。其他“真正的零”可以在 http://www.perlmonks.org/?node_id=464548< /a>.
Things that are false:
""
."0"
."0 but true"
is not one of those, so it's not false.Furthermore, Perl returns
"0 but true"
where a number is expected in order to signal that a function succeeded even though it returned zero. sysseek is an example of such a function. Since the value is expected to be used as a number, Perl is coded to consider it to be a number. As a result, no warnings are issued when it's used as a number, andlooks_like_number("0 but true")
returns true.Other "true zeroes" can be found at http://www.perlmonks.org/?node_id=464548.
“0 but true”的另一个示例:
DBI 模块使用“0E0”作为不影响任何记录的 UPDATE 或 DELETE 查询的返回值。它在布尔上下文中计算为 true(表示查询已正确执行),在数字上下文中计算为 0,表示查询没有更改任何记录。
Another example of "0 but true":
The DBI module uses "0E0" as a return value for UPDATE or DELETE queries that didn't affect any records. It evaluates to true in a boolean context (indicating that the query was executed properly) and to 0 in a numeric context indicating that no records were changed by the query.
我刚刚发现证据表明字符串“0 but true”实际上内置于解释器中,就像这里的一些人已经回答的那样:
I just found proof that the string "0 but true" is actially built into the interpreter, like some people here already answered:
当您想要编写一个返回整数值或false或undef(即错误情况)的函数时,您必须注意值零。返回它是 false 并且不应该指示错误条件,因此返回“0 but true”使函数返回值 true,同时在完成数学运算时仍然传回值零。
When you want to write a function that returns either an integer value, or false or undef (i.e. for the error case) then you have to watch out for the value zero. Returning it is false and shouldn't indicate the error condition, so returning "0 but true" makes the function return value true while still passing back the value zero when math is done on it.
“0 but true”是一个字符串,就像任何其他字符串一样,但由于 Perl 的语法,它可以起到有用的作用,即从函数返回整数零,而不会导致结果为“false”(在 Perl 看来)。
并且字符串不必是“0 but true”。 “0 但假”在布尔意义上仍然是“真”。
考虑:
所有这一切的结果是您可以:
并且让此代码能够打印“0”作为其输出:
"0 but true" is a string just like any other but because of perl's syntax it can serve a useful purpose, namely returning integer zero from a function without the result being "false"(in perl's eyes).
And the string need not be "0 but true". "0 but false" is still "true"in the boolean sense.
consider:
The upshot of all of this is you can have:
and have this code be able to print "0" as its output:
字符串“0 but true”仍然是一个特殊情况:
给出以下内容:(注意“警告”!)
...并且不要忘记 RTFM!
The string ``0 but true'' is still a special case:
give the following: (note the ``warning''!)
... and don't forget to RTFM!