这两个陈述的行为是否相同,还是会产生不同的结果?
if ( ... ) {...}
elsif( ... ) {... }
elsif( ... ) { ... }
else { ... }
given ( ... ) {
when ( ... ) { ... }
when ( ... ) { ... }
default { ... }
}
我发现了问题 - 修改后的第九个“当”它现在有效。
...
no warnings qw(numeric);
my $c = &getch();
given ( $c ) {
when ( $c == $KEY_LEFT and 1 > 0 ) { say 1; say $c }
when ( $c == $KEY_RIGHT ) { say 2; say $c }
when ( $c eq "\cH" or $c eq "\c?" ) { say 3; say $c }
when ( $c eq "\cC" ) { say 4; say $c }
when ( $c eq "\cX" or $c eq "\cD" ) { say 5; say $c }
when ( $c eq "\cA" ) { say 6; say $c }
when ( $c eq "\cE" ) { say 7; say $c }
when ( $c eq "\cL" ) { say 8; say $c }
when ( not( not $SpecialKey{$c} ) ) { say 9; say $c }
when ( ord( $c ) >= 32 ) { say 10; say $c }
default { say 11; say $c }
}
if ( $c == $KEY_LEFT and 1 > 0 ) { say 1; say $c }
elsif ( $c == $KEY_RIGHT ) { say 2; say $c }
elsif ( $c eq "\cH" or $c eq "\c?" ) { say 3; say $c }
elsif ( $c eq "\cC" ) { say 4; say $c }
elsif ( $c eq "\cX" or $c eq "\cD" ) { say 5; say $c }
elsif ( $c eq "\cA" ) { say 6; say $c }
elsif ( $c eq "\cE" ) { say 7; say $c }
elsif ( $c eq "\cL" ) { say 8; say $c }
elsif ( $SpecialKey{$c} ) { say 9; say $c }
elsif ( ord( $c ) >= 32 ) { say 10; say $c }
else { say 11; say $c }
close TTYIN;
答案 0 :(得分:4)
你所谓的“固定”版本现在在两个版本的代码中做了不同的事情。检查哈希中是否存在密钥与检查相关值是否为真完全不同。
您可以从散列中获取三个不同的真值 - 散列中是否存在密钥,是否定义了关联值以及关联值是true还是false。这段代码应该证明三者之间的区别:
#!/usr/bin/perl
use strict;
use warnings;
my %hash = (
key1 => undef,
key2 => 0,
key3 => 1,
);
foreach (qw(key1 key2 key3 key4)) {
check_key($_);
}
sub check_key {
my $k = shift;
print "Key $k ";
if (exists $hash{$k}) {
print 'exists. ';
} else {
print "doesn't exist. ";
}
print 'Value ';
if (defined $hash{$k}) {
print 'is defined ';
} else {
print 'is not defined ';
}
print 'and is ';
if ($hash{$k}) {
print "true\n";
} else {
print "false\n";
}
}
答案 1 :(得分:4)
无论您使用given/when
做什么,都可以使用if/elsif/else
。我们的想法是when/given
被认为更容易阅读,并且默认情况下可以自动使用 smartmatching ,而您必须使用if/else
语句指定智能匹配。
我没有解析您的代码以确保它们完全相同,但看起来您对if/elsif/else
和given/when
或多或少有正确的想法。
我从未真正理解对所谓的 switch语句的渴望。这是Perl程序员总是抱怨的东西 - 在Perl中缺少 switch语句。也许这是大多数Perl开发人员深情记忆的C事物。但我从未发现if/elsif/else
陈述不好。
让我感到困惑的是,当他们最终实现 switch语句时,他们没有将其称为switch
。为什么不呢?
为什么say
代替printnl
?
而且,为什么last
和next
代替break
和continue
。为什么不简单地使用其他语言已经使用的标准名称?
但这足以让Seinfeld的风格抱怨......
正如davorg所说,不存在的哈希密钥,存在但未定义的哈希密钥,以及已定义的哈希密钥,但被评估为假的哈希密钥之间存在很大差异:
例如:
use strict;
use warnings;
no warnings qw(uninitialized);
my %hash;
$hash{FOO} = "bar";
if (not exists($hash{BAR})) {
print "\$hash{FOO} doesn't exist\n";
}
if (not defined($hash{BAR})) {
print "\$hash{BAR} is undefined\n";
}
if (not $hash{BAR}) {
print "\$hash{BAR} evaluates to false\n";
}
if ($hash{BAR} eq undef) {
print "\$hash{BAR} is equal to 'undef'\n";
}
您可以看到$hash{BAR}
甚至不作为%hash
哈希中的键存在,但它也未定义,并且评估为false
。而且,您还可以看到它还评估为undef
(请注意我必须设置no warnings qw(uninitialized);
以防止它在我的上一个$hash{BAR}
语句中抱怨if
未初始化
但是,如果我这样做:
$hash{FOO} = bar;
$hash{BAR} = undef;
第一个if
语句不再评估为true
,因为密钥BAR
现在确实存在于哈希中,但该值仍未定义,仍然评估为false
而且,如果我这样做了:
$hash{FOO} = bar;
$hash{BAR} = 0;
$hash{BAR}
现在作为%hash
中的密钥存在,不再是undefined
,但它仍然评估为false
。
我只想简单地说:
if (not $hash{BAR}) {
因为它短而甜,可能做我想要的。但是,我必须理解哈希中存在键,对false
进行评估,而将defined
作为三个单独的事物之间的区别。如果您有一个可以返回NULL
字符串或零值的子例程,这一点很重要:
if (not foo($bar)) {
die qq(Error of some sort\n);
}
sub foo {
$bar = <FOO> or return;
return chomp($bar);
}
如果我的文件中有一个空行,它将返回一个NULL
字符串,但子程序仍将返回一个定义的值。以上可能不会做我想要的。
答案 2 :(得分:1)
添加另一个答案,因为我刚刚意识到真正的问题是什么。
你的“when($ SpecialKey {$ c})”相当于“if($ _ ~~ $ SpecialKey {$ c})”。而且“给定”将$ _设置为$ c,与“if($ c ~~ $ SpecialKey {$ c})”相同。当比较两个标量值(我假设这是我们在这里得到的)时,智能匹配运算符会查找数字值并在适当时使用“eq”或“==”。
因此,您的代码实际上等同于“if($ c == $ SpecialKey {$ c})”。这与“if($ SpecialKey {$ c})”完全不同。
答案 3 :(得分:0)
他们表现得完全平等。
答案 4 :(得分:0)
给定/何时具有隐式智能匹配:
大部分权力来自隐式智能匹配:
- 当($富)
醇>完全等同于
- 何时($ _ ~~ $ foo)
醇>
我不认为/ else是否会这样做(?)
请参阅perlsyn
编辑: 当使用给定/当OP的方式时,猜测这并不重要,但它仍然回答了问题:)