【发布时间】:2017-07-17 22:39:34
【问题描述】:
我以前认为unless 和if not 是完全等价的,但this Q&A 让我意识到它们在列表上下文中会产生不同的输出:
use strict;
use warnings;
use Data::Printer;
use feature 'say';
my %subs = (
unless => sub {
my ( $value ) = @_ ;
return "$value is a multiple of 3"
unless $value % 3 ;
},
if_not => sub {
my ( $value ) = @_ ;
return "$value is a multiple of 3"
if not $value % 3 ;
},
);
for my $name ( keys %subs ) {
my $sub = $subs{$name};
say $name;
my @results = map { $sub->($_) } 1 .. 10;
p @results;
}
输出
if_not
[
[0] "",
[1] "",
[2] "3 is a multiple of 3",
[3] "",
[4] "",
[5] "6 is a multiple of 3",
[6] "",
[7] "",
[8] "9 is a multiple of 3",
[9] ""
]
unless
[
[0] 1,
[1] 2,
[2] "3 is a multiple of 3",
[3] 1,
[4] 2,
[5] "6 is a multiple of 3",
[6] 1,
[7] 2,
[8] "9 is a multiple of 3",
[9] 1
]
上面的代码 sn-p 表明 unless 和 if not 导致子例程看到最后一个求值表达式的不同值。
这似乎是因为if not 认为not 是EXPR 的一部分,而unless 不认为它是EXPR 的一部分。
问题
是否还有其他代码使用示例,而这两者并不完全是同义词?
【问题讨论】:
-
"
if not认为not是EXPR的一部分,而unless不认为它是EXPR的一部分"没有多大意义。not是运算符,而if和unless是流控制语言单词。在您的unless情况下,根本没有not,因此“将not视为表达式的一部分”不适用。如果您也尝试过unless not ...,那么您会发现not是表达式的始终 的一部分,就像!一样。if和unless只是根据表达式的真相做出相反的行为。 -
如果“$value % 3”为假,则可以找到“return”EXPR。如果 "$value % 3" 为真,则找不到 "return" EXPR,"if_not" 将返回 "not $value % 3",而 "unless" 将返回 "$value % 3"。
-
我认为“问题”之前的最后一个陈述可能具有误导性。这里的重点是
return if EXPR;似乎有if(本身)是最后处理的东西(所以首先评估EXPR,然后评估其结果的if),而return unless EXPR;似乎有EXPR处理最后的。 (这与not无关。也与return-ing 无关。)如果if EXPR和unless EXPR导致不同的评估顺序,我认为这很重要。 -
@zdim:
if和unless都不返回值,因此无法“评估”。在没有显式return语句的情况下返回的值为EXPR,即$value % 3或not $value % 3。我不明白你为什么要说“这不是关于not。这也不是关于return-ing。” 很明显是。在这两种情况下,都会评估EXPR,然后可能会执行return,具体取决于EXPR的值。 -
@Borodin 同意——我认为你答案中的前两段清楚地表明了这一点。但是,我不同意“需要关闭”的问题。我认为这是一个很好的问题。基本构造行为的感知差异将是显着的,应该通过各种方式提出。它实际上如何表述并不重要——对于类似的事情,可以要求“其他示例”。
unless和if之间在操作中解释的“非差异”也很重要,因为unless通常被视为if not。
标签: perl