代码之家  ›  专栏  ›  技术社区  ›  sid_com

switch-和if语句之间的差异

  •  4
  • sid_com  · 技术社区  · 15 年前

    这两种说法的表现是一样的还是会产生不同的结果?

    if ( ... ) {...}
    elsif( ... ) {... }
    elsif( ... ) { ... }
    else { ... }
    

    .

    given ( ... ) {
        when ( ... ) { ... }
        when ( ... ) { ... }
        default { ... }
    }
    

    我发现了问题-修改后的第九个“when”现在可以工作了。

    ...
    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;
    
    5 回复  |  直到 13 年前
        1
  •  4
  •   Community Mohan Dere    9 年前

    不管你能用它做什么 given/when ,你可以 if/elsif/else . 我的想法是 when/given 假设更容易阅读,并且可以自动使用 智能匹配 默认情况下,必须指定智能匹配 if/else 陈述。

    我没有分析你的代码以确保它们是完全相同的,但是看起来你对 如果/elsif/else 给定/时间 .

    我从来没有真正理解过 switch语句 . 这是Perl编码人员经常抱怨的问题——缺少 switch语句 在Perl中。也许这是大多数Perl开发人员都很喜欢记住的C语言。但我从没找到 如果/elsif/else 说得那么糟。

    真正让我困惑的是,当他们最终实现 switch语句 ,他们没有这么叫 switch . 为什么不呢?

    为什么 say 而不是 printnl ?

    还有,为什么 last next 而不是 break continue . 为什么不直接使用其他语言已经使用的标准名称呢?

    不过,这种宋飞式的抱怨已经够多了。。。

    作为 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;
    

    第一次 如果 语句不再计算为 true 因为钥匙 BAR 现在在哈希中确实存在,但是该值仍然未定义,并且仍然评估为 .

    如果我这么做了:

    $hash{FOO} = bar;
    $hash{BAR} = 0;
    

    $hash{BAR} 现在作为密钥存在 %散列 ,它不再是 undefined ,但它仍然评估为 .

    我喜欢简单地说:

    if (not $hash{BAR}) {
    

    因为它又短又甜,而且可能是我想要的。但是,我必须理解哈希中的密钥存在性的差异,评估 ,而不是 defined 作为三个独立的东西。如果有一个子例程可以返回 NULL 字符串或零值:

    if (not foo($bar)) {
        die qq(Error of some sort\n);
    }
    
    sub foo {
        $bar = <FOO> or return;
        return chomp($bar);
    }
    

    如果我的文件中有空行,它将返回 无效的 字符串,但子例程仍将返回定义的值。上面的可能不是我想要的。

        2
  •  4
  •   Dave Cross    15 年前

    你所谓的“固定”版本现在在代码的两个版本中做了不同的事情。检查散列中是否存在一个键,与检查关联的值是否为真是完全不同的。

    从散列中可以得到三个不同的真值:密钥是否存在于散列中,是否关联的值被定义,关联的值是否为真或假。此代码应说明三者之间的区别:

    #!/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";
      }
    }
    
        3
  •  1
  •   Dave Cross    15 年前

    当我刚刚意识到真正的问题是什么时,我又补充了一个答案。

    你的“when($SpecialKey{$c})”等同于“if($\~$SpecialKey{$c})”。而且由于“given”将$设为$c,这与“if($c~~$SpecialKey{$c})”相同。当比较两个标量值时(我假设这就是我们在这里得到的),smart match操作符会查找数字值,并根据需要使用“eq”或“==”。

    因此,您的代码实际上相当于“if($c==$SpecialKey{$c})”。这与“if($SpecialKey{$c})”完全不同。

        4
  •  0
  •   Thariama    15 年前

    他们表现完全平等。

        5
  •  0
  •   Øyvind Skaar    15 年前

    给定/何时具有隐式智能匹配:

    大部分的力量来自于隐性的智能匹配:

    1. 何时($foo)

    完全等同于

    1. 当($~~$foo)

    我不认为如果/否则会那样做(?)

    perlsyn

    编辑: 我猜这在使用given/when the way OP时并不重要,但它仍然回答了这个问题:)