在 Perl 代码中最好地使用if
vs有哪些指导方针?unless
在某些情况下是否有充分的理由偏爱其中一种?
9 回答
在 Perl 最佳实践中,建议永远不要使用unless
. 就个人而言,我认为这很疯狂。
只要有一个简单的条件,我就会使用unless
,否则我会写成if( ! ... )
. 我发现该unless
版本更具可读性,尤其是用作后缀时:
do_something() unless $should_not_do_that;
我建议避免unless
任何时候事情变得更复杂,比如你什么时候会拥有elsif
或else
阻塞。(幸运的是,或者不幸的是,根据您的观点,没有elsunless
)
此外,任何时候条件都是由其他布尔值组成的复杂表达式。例如,
unless( $foo and !$bar )
非常令人困惑,并且与等效的if
.
除了一个深奥的案例1 unless
只是if !
. 它的存在是为了让您编写更清晰、更具表现力的代码。当它达到这个目标时应该使用它,当它损害它时应该回避它。
我发现unless
对循环中的流量控制最有用。例如
while (<$fh>) {
next unless /\S/;
# ...
}
对于简单的否定,我发现它比否定更清楚——阅读代码时if
很容易错过那个领先。!
unless ($condition) {
do_something();
}
if (!$condition) {
do_something();
}
但是不要写unless ... else
,因为那很不和谐。
在后缀形式中,它提供了有关通过代码的预期路径的提示。
do_normal_thing() unless $some_unlikely_condition;
1) 评估的最后一个表达式不同,这可能会影响 subs 的行为,而无需显式
return
.
一个经验法则是“除非”可能不应该经常使用。
它在后缀形式中特别有用,例如:
delete_old_widgets() unless $old_widget_count == 0
不应该使用的情况,除非:
- 带有复合条件(and, or, not)
- 带有 else 子句
我最近花了一个小时试图向某人解释两个嵌套的“除非”子句是如何工作的,如果不使用布尔逻辑将它们反转为 if 语句,就很难破译它们。
如果您尝试将其转换为英语,它将有助于指导您。
一个简单的除非工作正常。例如。
“除非你保持安静,否则我会不理你”。
unless ($quiet) {
ignore();
}
虽然我认为这同样有效
'如果你不安静,我会不理你'
if (not $quiet) {
ignore();
}
当它开始变得复杂时,就是你有否定的时候。
“除非你不吵,否则我不理你”
unless ( ! $noisy) {
ignore();
}
好得多写成
'如果你吵闹,我会不理你'
if ($noisy) {
ignore();
}
因此,如果您也有否定词,请不要使用“除非”。
也不要使用“除非其他”
unless ($quiet) {
ignore();
}
else {
give_a_sweet();
}
'除非你安静,否则我会不理你,否则我会给你一个甜蜜'
通过反转条件来改变它。
if ($quiet) {
give_a_sweet();
}
else {
ignore();
}
'如果你安静,我会给你一个甜蜜,否则我会不理你'。
有多个条件,它会变得混乱。
unless ($quiet and not $fidgit) {
punish();
}
“除非你安静不烦躁,否则我会惩罚你”。
(对不起,我的理解在这里失败了!)
再次,否定它。
if (not $quiet or $fidgit) {
punish();
}
'如果你不安静,或者你烦躁,我会惩罚你'。
即使对于最简单的情况,使用“除非”的问题,他们经常(由你自己或通过
我希望这可以清楚地说明您何时应该或不应该使用除非?
(除非你没有其他意见?)
虽然我理解这类问题的动机,但我不认为归结为使用类似的东西真的很明智unless
成具体的经验法则。这就像 Perl 中的许多辅助语法一样,只是为程序员提供了一个小小的便利,以帮助他们根据自己的判断更清楚地表达自己;在整个“Programming Perl”中,我看到的主要开发人员以多种方式说的不止一种。没有更高的目的或合理化。我很清楚这解决了这个问题,但我对使用它的唯一限制是看到它服务于使代码更清晰的更广泛目的。如果是这样,那么一切都很好。识别代码是否易于理解本身就很直观,不能简化为关于内置修饰符/运算符/整体语法的每个细微差别的大量过度概括的使用条件,
我的意见是永远不要使用除非。我的理由是:
- 我认为语法使代码更难阅读。使用单一的 if 方法可以让事情变得更简单、更一致。
- 如果您稍后需要添加 else 语句,您应该真正将 unless 更改为 if。如果它已经是一个if,那就更容易了。
- 如果 unless 语句中的逻辑变得更复杂,那么您最终可能会得到奇怪的代码,例如“除非 (x == 5 && y != 7)。这很奇怪,因为第二次检查时出现双重否定。
- 还有其他否定事物的方法,即 x != 5
- 它与其他语言更加一致。我不知道有任何其他语言有一个除非声明,我认为这是有充分理由的。
在 perl 中,实际上有 4 种方法可以编写 if 语句,如果,除非,然后将检查放在行尾而不是开头。我更喜欢与其他语言一致的单一一致方法。
只是我的 0.02 美元。
恰到好处...
在 Perl 最佳实践中,建议永远不要使用除非。就个人而言,我认为这很疯狂。
经过 20 多年更喜欢 Perl 而不是它的任何替代品(如果没有 Perl 提供模板,其中大部分将不存在),我不仅同意“疯狂”的判决,而且我很惊讶(担心)听到“最佳实践” '想要摆脱它。
也就是说,我更喜欢为了清晰而编写的代码,而不是一些 Perl 程序员“仅仅因为他们可以”而采用的隐含混淆的替代方案。“除非”是“如果”的明确反义词,因此是在“如果”条件中嵌入否定的非常有用的替代方案,特别是在条件包含多个运算符时。即使后面跟着 else/elsif,这个理由也适用。
可能只是个人意见,但我喜欢在 if 条件以 ! 开头时使用除非!
语法 if(!$condition) 等价于 unless($condition),同样如果你交换条件的 NOT'ing。
我个人更喜欢只使用 IF 语句。为什么?因为记的少。如果您有 100 行代码,其中一半使用 unless(),另一半使用 if(),则与仅使用 if() 语句相比,您将需要花费更多时间调试它。
但是,您可能会“掌握”除非和如果的窍门,因此在两者之间进行切换根本不需要时间。但这不仅仅是 if() 与 unless() 的关系。别忘了那...
if($condition) {
#passed-condition code
} else {
#failed-condition code
}
……相当于……
unless(!$condition) {
#passed-condition code
} else {
#failed-condition code
}
但是 if(){...}elsif(){...} 呢?您如何将其等效为除非(){...}elsunless(){...}?逻辑越复杂,在 if() 和 unless() 之间切换就越困难。您需要记住和平衡的内存越少,您调试自己的代码的速度就越快。