1

我有一种情况,我希望变量作为字符串或数字传递给我。

IE

sub foo {
    # These can be either strings or numbers
    my ($bar, $var, $star) = @_;

    # I need to check to see if $bar is the number 0 (zero)
    if ($bar == 0) {
        # Do super magic with it
    }
}

$bar不幸的是,当 Perl包含一个字符串时,它试图发挥超级魔力。

$bar当且仅当它是数字0(零)时,我如何告诉 Perl 做超级魔术?

我理解 Perl 从根本上解释是基于上下文的,这是这里的根本问题。这个问题的一个可能的解决方案是使用正则表达式,这很好,但我想知道是否还有另一个更“直截了当”的解决方案。

提前致谢。

4

4 回答 4

4

我个人会同意@Disco3 的评论所说的。

if ($bar eq 0) { ... }

这适用于$bar = 0$bar = 'foo'$bar = 123给出预期的结果。

不过,这是一个有趣的事实:

use Benchmark qw(cmpthese);
my $bar = '0';

cmpthese(-1, {
  'quoted'    => sub { $bar eq '0'    },
  'unquoted'  => sub { $bar eq 0      },
  'regex'     => sub { $bar =~ m/^0$/ },
});

对这三种解决方案进行基准测试告诉我们,未引用0是最快的方法。

               Rate    regex   quoted unquoted
regex     4504851/s       --     -70%     -76%
quoted   15199885/s     237%       --     -19%
unquoted 18828298/s     318%      24%       --
于 2012-07-09T15:18:22.490 回答
2

为什么不:

if ( $bar =~ m/^0$/ ) {
于 2012-07-09T15:08:59.407 回答
2

这取决于您所说的“数字0”是什么意思。显然,你包含的一个字符串0是零。但是你对三个字符串0.0呢?

如果您只想匹配一个字符串0,请使用

if ($bar eq '0') {
   ...
}

如果您想匹配 Perl 认为的数字零,请使用

use Scalar::Util qw( looks_like_number );

if (looks_like_number($bar) && $bar == 0) {
   ...
}
于 2012-07-09T16:06:37.677 回答
0

之间looks_like_number和数值比较,你可以很容易地得到相当不错的结果:

use Scalar::Util qw(looks_like_number);
use Test::More tests => 7;

sub is_numerically_zero {
    my ($string) = @_;

    return (looks_like_number($string) and $string == 0);
}

for my $string (qw(0 0.0 0e0), '  0  ') {
    ok(is_numerically_zero($string));
}

for my $string (qw(duckies 123), '') {
    ok(not is_numerically_zero($string));
}

这假设您不想只匹配文字 string '0'

于 2012-07-09T18:25:29.100 回答