加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Perl三元错误地输入“else”条款?

发布时间:2020-12-15 21:55:30 所属栏目:大数据 来源:网络整理
导读:我有以下代码: # List of testsmy $tests = [("system_test_builtins_sin","system_test_builtins_cos","system_test_builtins_tan")];# Provide overrides for certain variables that may be needed because of special cases# For example,cos must be e
我有以下代码:
# List of tests
my $tests = [("system_test_builtins_sin","system_test_builtins_cos","system_test_builtins_tan")];

# Provide overrides for certain variables that may be needed because of special cases
# For example,cos must be executed 100 times and sin only 5 times.
my %testOverrides = (
    system_test_builtins_sin => {
        reps => 5,},system_test_builtins_cos => {
        reps => 100,);

my %testDefaults = (
    system_test_reps => 10,);

# Execute a system tests
foreach my $testName (@$tests)
{
    print "Executing $testNamen";
    my $reps;

    if (exists $testOverrides{$testName}{reps})
        { $reps = $testOverrides{$testName}{reps}; }
    else
        { $reps = $testDefaults{system_test_reps}; }
    print "After long if: $repsn";
    exists $testOverrides{$testName}{reps} ? $reps = $testOverrides{$testName}{reps} : $reps = $testDefaults{system_test_reps};
    print "After first ternary: $repsn";
    exists $testOverrides{$testName}{reps} ? $reps = $testOverrides{$testName}{reps} : print "Override not found.n";
    print "After second ternary: $repsn";
}

这给出了以下输出:

Executing system_test_builtins_sin
After long if: 5
After first ternary: 10
After second ternary: 5
Executing system_test_builtins_cos
After long if: 100
After first ternary: 10
After second ternary: 100
Executing system_test_builtins_tan
After long if: 10
After first ternary: 10
Override not found.
After second ternary: 10

这个输出是最意想不到的!我不明白为什么第一个三元似乎总是在执行“if false”条款.它总是赋值为10.我也尝试将“false”子句改为$reps = 6,我看到它总是得到值6.为什么三元的逻辑取决于第三个的内容(如果虚假)条款?

解决方法

这是一个更简单的脚本来说明问题:
#!/usr/bin/perl

use strict;
use warnings;

my $x;

1 ? $x = 1 : $x = 0;
print "Without parentheses,$x = $xn";

1 ? ($x = 1) : ($x = 0);
print "With parentheses,$x = $xn";

它产生这个输出:

Without parentheses,$x = 0
With parentheses,$x = 1

我不确定赋值和?:之间的关系可以通过运算符优先级来完整解释. (例如,我相信在某些情况下C和C的行为会有所不同.)

运行perldoc perlop并搜索“条件运算符”,或查看here;它涵盖了这个确切的问题(比我在这里更简洁).

在任何情况下,我认为使用if / else语句比使用?:运算符更清晰.或者,既然“true”和“false”分支都分配给同一个变量,更好地使用?:将改变这个:

exists $testOverrides{$testName}{reps}
    ? $reps = $testOverrides{$testName}{reps}
    : $reps = $testDefaults{system_test_reps};

对此:

$reps = ( exists $testOverrides{$testName}{reps}
          ? testOverrides{$testName}{reps}
          : $testDefaults{system_test_reps} );

但同样,我必须包裹线以避免滚动这一事实很好地表明if / else会更清晰.

您可能还会考虑使用//运算符,除非您遇到不支持它的古老版本的Perl. (它是由Perl 5.10引入的.)它也被称为“定义或”运算符.这个:

$x // $y

相当于

defined($x) ? $x : $y

所以你可以写:

$reps = $testOverrides{$testName}{reps} // $testDefaults{system_test_reps};

这没有完全相同的语义,因为它使用defined而不是exists来测试表达式;如果$testOverrides {$testName} {reps}存在但值为undef,它的行为会有所不同.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读