my $target_type = (defined($item->{target_type}) && $item->{target_type})
? $item->{target_type}
: "";
my $target_id = (defined($item->{target_id}) && $item->{target_id})
? $item->{target_id}
: "";
为什么开发人员在几乎相同的条件下使用&&
?
答案 0 :(得分:6)
显然他是腰带和吊带类型。 (defined($x) && $x)
几乎等同于$x
,因为undef
是假的。 (不同之处在于如果$x
为undef
,那么(defined($x) && $x)
将是Perl的特殊假值,已定义,但在这种情况下没有区别。)可能存在曾经是一个不同的条件(如$x > 0
),defined
测试是必要的,以避免有关未初始化值的警告。然后有人删除了这个条件,并没有考虑删除现在不必要的defined
。
使用(defined($x) && $x)
(作为onon15 points out)的另一个原因是强调未来的维护程序员可能未定义$x
。就个人而言,我会对此进行评论,但TIMTOWTDI。
答案 1 :(得分:2)
尽管&& amp;的右侧可以单独使用,我已经多次看到这种用法作为人类读者的语义暗示,$item->{target_type}
可能没有被定义。
因此,即使可以删除LHS并保持相似的行为,维护者也可能很容易误以为不需要检查是否定义了值。 (除非在紧密的循环中,额外评估的成本可以忽略不计,甚至在循环内部,它很可能通过解释器中的优化来删除。)
答案 2 :(得分:2)
非常简短的回答:这是为了避免在较旧的perls中使用“未初始化值”警告并在此情况下分配默认定义值。在v5.10及更高版本中,您将使用defined-or运算符:
$scalar //= "";
答案 3 :(得分:1)
&&
是一个“逻辑短路”运算符。首先,他正在测试$item->{targ_type}
的定义。如果且仅当它被定义时(即&&
的左侧为真),则他测试以查看$item->{target_type}
是否包含真值。如果两个条件均为真,则$target_type
(以及之后的$target_id
)会分配$item->{target_type}
或$item->{target_id}
中的值。如果其中一个条件为false,则分配一个空字符串。
更新:尝试阅读提出构造的程序员的想法:也许代码以导致这种情况的方式发展,并且程序员没有想到它足够长的时间来认识到它是不必要的。也许程序员对于定义,真理,虚假以及Perl中哪些类型的值是“错误”之间的区别是不安全的。
答案 4 :(得分:1)
回答你的问题需要精神阅读,但这里有几个原因按概率排序:
undef
的真实性感到不安,defined undef && undef
评估""
并使表达的其余部分没有实际意义,或两者兼而有之defined
测试才能正常运行的内容,例如defined $x && $x ne ''
。 defined
测试是从编辑遗留下来的,对维护者来说是负面价值。undef
,因此明确地对其进行了测试。有更好的方法可以做到这一点,不会让未来的读者猜测出意图可能是什么。比方说,评论。$item->{target_type}
可能包含一个带有重载布尔转换的对象,计算成本很高,而且您正在寻找一种自我挫败的微优化。这种情况极不可能发生。但是很有趣。答案 5 :(得分:0)
情况并非如此。
首先,他测试定义性
defined($item->{target_type})
使用未定义的值进行操作时,某些操作没有意义。
在第二种情况下,他会测试真值或假值
$item->{target_type}
但是,由于undef
是假值,第二次测试涵盖两种情况。
在某些情况下,需要类似的模式,例如在测试参考文献的内容时。
my $ref1 = "true";
my $ref2 = \("true");
if (ref $ref1 eq 'SCALAR' and $$ref1) {
# This does not get executed
}
if (ref $ref2 eq 'SCALAR' and $$ref2) {
# This does get executed
}