我有一种情况,我希望变量以字符串或数字的形式传递给我。
即
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
}
}
不幸的是,当Perl包含一个字符串时,它试图在$bar
上执行超级魔法。
当且仅当数字 0(零)时,我如何告诉Perl在$bar
上做超级魔法?
我理解Perl从根本上解释了上下文,这是这里的根本问题。这个问题的一个可能的解决方案是使用正则表达式,这很好,但我想知道是否还有另一个更“直接”的解决方案。
提前致谢。
答案 0 :(得分: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% --
答案 1 :(得分:2)
为什么不:
if ( $bar =~ m/^0$/ ) {
答案 2 :(得分: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) {
...
}
答案 3 :(得分: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));
}
这假设您不希望仅匹配文字字符串'0'
。