235

我试过了:

$var = false;
$var = FALSE;
$var = False;

这些都不起作用。我收到错误消息

使用“strict subs”时不允许使用裸词“false”。
4

9 回答 9

298

在 Perl 中,以下条件的计算结果为 false:

0
'0'
undef
''  # Empty scalar
()  # Empty list
('')

其余的都是真的。true或没有裸词false

于 2009-06-24T04:10:16.550 回答
74

我遇到的最完整、最简洁的 false 定义是:

任何字符串化为空字符串或字符串0的内容都是错误的。其他一切都是真的。

因此,以下值是错误的:

  • 空字符串
  • 数值为零
  • 未定义的值
  • 具有重载布尔运算符的对象,该运算符评估上述之一。
  • 一个神奇的变量,在获取时评估为上述之一。

请记住,空列表文字在标量上下文中计算为未定义的值,因此它的计算结果为 false。


关于“真零”的注释

虽然字符串化的数字0是假的,但数字化为零的字符串不一定。唯一的假字符串是0空字符串。任何其他字符串,即使它的数值为零,也是如此。

以下是作为布尔值和零作为数字的字符串:

  • 没有警告:
    • "0.0"
    • "0E0"
    • "00"
    • "+0"
    • "-0"
    • " 0"
    • "0\n"
    • ".0"
    • "0."
    • "0 but true"
    • "\t00"
    • "\n0e1"
    • "+0.e-9"
  • 带有警告:
    • Scalar::Util::looks_like_number返回 false的任何字符串。(例如"abc"
于 2011-04-13T20:53:15.150 回答
61

Perl 没有本机布尔类型,但您可以使用整数或字符串的比较来获得相同的行为。Alan 的示例是使用整数比较的一种很好的方法。这是一个例子

my $boolean = 0;
if ( $boolean ) {
    print "$boolean evaluates to true\n";
} else {
    print "$boolean evaluates to false\n";
}

我在某些程序中所做的一件事是使用常量添加了相同的行为:

#!/usr/bin/perl

use strict;
use warnings;

use constant false => 0;
use constant true  => 1;

my $val1 = true;
my $val2 = false;

print $val1, " && ", $val2;
if ( $val1 && $val2 ) {
    print " evaluates to true.\n";
} else {
    print " evaluates to false.\n";
}

print $val1, " || ", $val2;
if ( $val1 || $val2 ) {
    print " evaluates to true.\n";
} else {
    print " evaluates to false.\n";
}

在“使用常量”中标记的行定义了一个名为 true 的常量,它总是计算为 1,一个名为 false 的常量总是计算为 0。由于 Perl 中定义常量的方式,以下代码行也失败了:

true = 0;
true = false;

错误消息应显示类似“无法修改标量赋值中的常量”之类的内容。

我在您询问的有关比较字符串的评论之一中看到了这一点。你应该知道,因为 Perl 在标量变量中结合了字符串和数字类型,所以你有不同的语法来比较字符串和数字:

my $var1 = "5.0";
my $var2 = "5";

print "using operator eq\n";
if ( $var1 eq $var2 ) {
    print "$var1 and $var2 are equal!\n";
} else {
    print "$var1 and $var2 are not equal!\n";
}

print "using operator ==\n";
if ( $var1 == $var2 ) {
    print "$var1 and $var2 are equal!\n";
} else {
    print "$var1 and $var2 are not equal!\n";
}

这些运算符之间的区别是 Perl 中一个非常常见的混淆来源。

于 2009-06-24T07:24:29.313 回答
16

我推荐use boolean;。不过,您必须从 cpan安装布尔模块。

于 2010-05-03T11:16:18.427 回答
16

我的最爱一直是

use constant FALSE => 1==0;
use constant TRUE => not FALSE;

它完全独立于内部表示。

于 2015-10-08T11:00:17.730 回答
9

我遇到了一个教程,其中很好地解释了Perl 中哪些值是真值和假值。它指出:

以下标量值被认为是错误的:

  • undef- 未定义的值
  • 0数字 0,即使您将其写为 000 或 0.0
  • ''空字符串。
  • '0'包含单个 0 数字的字符串。

所有其他标量值,包括以下内容都为真:

  • 1任何非 0 数
  • ' '里面有空格的字符串
  • '00'字符串中有两个或多个 0 字符
  • "0\n"一个 0 后跟一个换行符
  • 'true'
  • 'false'是的,即使字符串“假”的计算结果为真。

还有另一个很好的教程解释了Perl true 和 false

于 2015-04-13T12:56:37.700 回答
7

bobf对布尔值 给出的漂亮解释:对还是错?快速参考指南

不同值的真值测试

                       Result of the expression when $var is:

Expression          | 1      | '0.0'  | a string | 0     | empty str | undef
--------------------+--------+--------+----------+-------+-----------+-------
if( $var )          | true   | true   | true     | false | false     | false
if( defined $var )  | true   | true   | true     | true  | true      | false
if( $var eq '' )    | false  | false  | false    | false | true      | true
if( $var == 0 )     | false  | true   | true     | true  | true      | true
于 2013-11-27T11:32:16.923 回答
0

使用以下文件前缀,这将添加到您的 perl 脚本 eTRUE 和 eFALSE,它实际上是 REAL(!) true 和 false(就像 java 一样)

#!/usr/bin/perl
use strict;
use warnings;

use constant { #real true false, compatible with encode_json decode_json for later (we don't want field:false... will be field:0...)
                eTRUE  =>  bless( do{\(my $o = 1)}, 'JSON::PP::Boolean' ),
                eFALSE =>  bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' )
             };

实际上,您应该使用它的原因很少。

我的原因是使用 JSON 时,我将 0 和 1 作为键的值,但是这个 hack 将确保在您的脚本中保留正确的值。

于 2014-01-15T10:48:28.567 回答
-2

Raku 中的布尔值(以前称为 Perl_6 的编程语言):

~$ raku
Welcome to ™ v2021.06.
Implementing the ™ programming language v6.d.
Built on MoarVM version 2021.06.

To exit type 'exit' or '^D'

> my $var = False;
False
> say $var;
False

> say $var.^name
Bool
> say $var.WHAT
(Bool)

> say ++$var
True
> say --$var
False

> say $var.Int
0
> say $var.Int + 1
1
> say ($var.Int + 1).Bool
True
> say $var.Int - 1
-1
> say ($var.Int - 1).Bool
True

> say $var.succ
True
> say $var.Int.succ
1
> say $var.pred
False
> say $var.Int.pred
-1

> say ++($var.Int); #ERROR
Cannot resolve caller prefix:<++>(Int:D); the following candidates
match the type but require mutable arguments:
    (Mu:D $a is rw)
    (Int:D $a is rw --> Int:D)
    #<SNIP>    
> say --($var.Int); #ERROR
Cannot resolve caller prefix:<-->(Int:D); the following candidates
match the type but require mutable arguments:
    (Mu:D $a is rw)
    (Int:D $a is rw --> Int:D)
    #<SNIP>

> exit

https://docs.raku.org/type/Bool
https://docs.raku.org/language/syntax#index-entry-Boolean_(literals)

于 2021-09-12T03:37:27.627 回答