我是新来的。在阅读了如何询问和格式化之后,我希望这将是一个好问题。我对perl不是很熟练,但它是我最熟悉的编程语言。
我尝试将Perl应用于现实生活,但我没有得到很好的理解 - 特别是不是来自我的妻子。我告诉她:
如果她晚上没有给我带来 3 啤酒,那意味着我得到了零(或没有)啤酒。
正如你可能猜到的那样,没有太大的成功。 :(
现在事实上。来自perlop:
一元“!”执行逻辑否定,即“不”。
语言,有boolean
种类型(只能有两个“值”)是可以的:
如果它不是一个值 - > 必须另一个。
如此自然:
!true -> false
!false -> true
但是perl没有boolean
个变量 - 只有truth system
,一切都不是0
,'0'
undef
,{{1} } 是真的。将逻辑否定应用于非逻辑值时出现问题,例如号。
E.g。如果某个数字不是3 ,则表示 IS ZERO 或为空,而不是现实生活含义,如果某些内容不是3,意味着它可以是除了3 之外的所有东西(例如也是零)。
所以下一个代码:
''
打印:
use 5.014;
use Strictures;
my $not_3beers = !3;
say defined($not_3beers) ? "defined, value>$not_3beers<" : "undefined";
say $not_3beers ? "TRUE" : "FALSE";
my $not_4beers = !4;
printf qq{What is not 3 nor 4 mean: They're same value: %d!\n}, $not_3beers if( $not_3beers == $not_4beers );
say qq(What is not 3 nor 4 mean: @{[ $not_3beers ? "some bears" : "no bears" ]}!) if( $not_3beers eq $not_4beers );
say ' $not_3beers>', $not_3beers, "<";
say '-$not_3beers>', -$not_3beers, "<";
say '+$not_3beers>', -$not_3beers, "<";
此外:
defined, value><
FALSE
What is not 3 nor 4 mean: They're same value: 0!
What is not 3 nor 4 mean: no bears!
$not_3beers><
-$not_3beers>0<
+$not_3beers>0<
什么是不是4 IS 1 ,而不是4!
上述与妻子的陈述是“假的”(意思是0):),但是真的想教我的儿子 Perl和他,过了一会儿,问我的妻子:为什么,如果什么不是3意味着它是0?。
所以问题是:
perl -E 'say !!4'
每次都是1 !0
不是任何随机数,而是0。!0
?答案 0 :(得分:11)
我认为你在很大程度上关注否定,而太多关于Perl布尔的意思。
什么是真相?检测到更高电压x伏特。
在更高的抽象级别:如果此位置位。
比特序列的抽象可以被认为是整数。这个整数是假的吗?是的,如果没有设置位,即整数为零。
面向硬件的语言可能会使用这种真理定义,例如: C和所有C后代都包含Perl。
0
的否定可能是按位否定 - 所有位都翻转为1
- ,或者我们只将最后一位设置为1
。结果通常分别解码为整数-1
和1
,但后者更节能。
方便在处理计数时将所有数字都想象为 true 为零
my $wordcount = ...;
if ($wordcount) {
say "We found $wordcount words";
} else {
say "There were no words";
}
或
say "The array is empty" unless @array; # notice scalar context
像Perl这样的实用语言可能会认为零是假的。
没有理由说任何数字都是假的,每个数字都是明确定义的实体。真理或虚假仅通过谓词表达,表达可以是真或假。只有这个真值才能被否定。 E.g。
¬(x ≤ y) where x = 2, y = 3
是假的。许多具有强大数学基础的语言不会考虑任何错误,而是一种特殊的虚假价值。在Lisps中,'()
或nil
通常为false,但0
通常为真。也就是说,如果值不是零,则该值仅为真!
在这种数学语言中,!3 == 0
可能是类型错误。
my $beers = ...;
if (not $beers) {
say "Another one!";
} else {
say "Aaah, this is good.";
}
啤酒计数变量的升级只是告诉我们你是否有啤酒。考虑!!
是一个boolification运算符:
my $enough_beer = !! $beers;
boolification并不涉及具体数量。但也许任何数量≥3都是好的。然后:
my $enough_beer = ($beers >= 3);
否定啤酒是不够的:
my $not_enough_beer = not($beers >= 3);
或
my $not_enough_beer = not $beers;
fetch_beer() if $not_enough_beer;
Perl标量并不代表整个世界。特别是,not 3
不是所有不是三个实体的集合。表达式3
是真值吗?是。因此,not 3
是一个假名值。
4 == not 3
的建议行为可能是不合适的:4
和“所有不是三的东西”不是相等,这四个只是其中之一许多事情不是三个。我们应该写得正确:
4 != 3 # four is not equal to three
或
not( 4 == 3 ) # the same
将!
和not
视为逻辑否定 - 可能会有所帮助,但除之外不会。
引入数学谓词可能是值得的:表达式可以是真或假。如果我们只通过明确的测试“创造”真实性,例如length($str) > 0
,那么您的问题就不会出现。我们可以为结果命名:my $predicate = (1 < 2)
,但我们可以决定永远不打印出来,而是:print $predicate ? "True" : "False"
。这避免了考虑 true 或 false 的特殊表示的问题。
直接考虑值为真/假将只是一个捷径,例如foo if $x
可以被视为
foo if defined $x and length($x) > 0 and $x != 0;
Perl就是关于捷径的。
教授这些快捷方式,以及perl的各种上下文以及它们出现的位置(数字/字符串/布尔运算符)可能会有所帮助。
答案 1 :(得分:8)
- 正如我已经说过的,我不太了解其他语言 - 每种语言都是!3 == 0?
是。在C(以及C ++)中,它是相同的。
void main() {
int i = 3;
int n = !i;
int nn = !n;
printf("!3=%i ; !!3=%i\n", n, nn);
}
打印(参见http://codepad.org/vOkOWcbU)
!3=0 ; !!3=1
- 如何向我的儿子解释这个
很简单。 !3
表示“与某些非假值相反,这当然是假的”。这被称为“上下文” - 在由否定运算符强加的布尔上下文中,“3”不是数字,它是真/假的陈述。
结果也不是“零”,而只是方便Perl表示false的东西 - 如果在数字上下文中使用则变为零(但如果在字符串上下文中使用则为空字符串 - 请参阅{之间的差异} {1}}和0 + !3
)
布尔上下文只是一种特殊的标量上下文,不会执行任何字符串或数字的转换。 (
perldoc perldata
)
- 为什么perl有这个设计,所以为什么!0每次都是
见上文。除了其他可能的原因(虽然我不知道这是否是Larry的主要原因),C具有相同的逻辑,Perl从C中获取了大量的语法和思想。
有关非常好的基础技术细节,请参阅此处的答案:“What do Perl functions that return Boolean actually return”和此处:“Why does Perl use the empty string to represent the boolean false value?”
- 这里有什么需要“落后”的东西比!0不是任何随机数,而是0。
除了简单的实施之外没有别的。产生“1”比随机数更容易。
如果你问一个不同的问题“为什么它是1而不是原来的#被否定得0”,答案很简单 - 到时候Perl解释器得到否定零,它不再知道/记住零是“!3”的结果,而不是导致值为零/假的其他表达式。
答案 2 :(得分:3)
如果您想测试一个数字不是3,请使用:
my_variable != 3;
使用语法!3
,因为!
是一个布尔运算符,首先将3
转换为布尔值(即使perl
可能没有官方布尔类型,它仍然以这种方式工作),因为它非零,意味着它被转换为等价的true
。然后,!true
产生false
,当转换回整数上下文时,它会给出0
。继续该逻辑显示!!3
如何将3
转换为true
,然后将其转换为false
,再次反转回true
,如果此值为在整数上下文中使用,转换为1
。对于大多数现代编程语言来说都是如此(尽管可能不是一些更以逻辑为中心的编程语言),尽管确切的语法可能会因语言而有所不同......
答案 3 :(得分:0)
逻辑上否定错误值需要选择某些值来表示结果的真值。 “1”和任何选择一样好。我会说返回哪个值并不重要(或者相反,重要的是你不要依赖任何特定的真值返回)。