在Perl中,可以为子程序的参数指定一种数据类型吗?例如。在数字上下文中使用dualvar时,例如exit:
use constant NOTIFY_DIE_MAIL_SEND_FAILED => dualvar 3, 'NOTIFY_DIE_MAIL_SEND_FAILED';
exit NOTIFY_DIE_MAIL_SEND_FAILED;
在这种情况下Perl如何知道,退出需要一个数字参数?我没有看到为子程序的参数定义数据类型的方法,就像在Java中一样? (在那里我可以理解数据类型是如何知道的,因为它是明确定义的)
答案 0 :(得分:2)
在Perl中,标量同时是数字和字符串。区分字符串和数字不是变量本身,而是您使用的运算符。虽然添加+
仅使用数字,但连接.
仅使用字符串。
更强类型的语言,例如Java,加法运算符兼作加法和连接运算符,因为它可以访问类型信息。
"1" + 2 + 3
在Java中仍然生病,而Perl可以清楚地区分"1" + 2 + 3 == 6
和"1" . 2 . 3 eq "123"
。
您可以通过添加0
或连接空字符串来强制变量的数字或字符串上下文:
sub foo {
my ($var) = @_;
$var += 0; # $var is numeric
$var .= ""; # $var is stringy now
}
答案 1 :(得分:2)
双变量的全部意义在于它根据您的需要表现为数字或文本。在那些不明显的情况下(对你来说比对perl更重要)然后说清楚。
exit 0 + NOTIFY_DIE_MAIL_SEND_FAILED;
至于显式输入参数,这不是内置的.Perl是一种比Java更动态的语言,因此检查/强制每个参数或变量的类型并不常见。特别是,perl sub可以接受不同数量的参数甚至不同的结构。
如果您想验证参数(例如,对于外部API),请尝试Params::Validate
之类的内容答案 2 :(得分:1)
Perl与Java完全不同 - Perl
是dynamically typed
语言,因为它不要求在compile time
处输入变量。
鉴于,Java
为statically typed
(如您所知)
Perl根据使用的context
确定变量的类型。
只能two context
: -
上下文由使用的operator
或function
定义..
对于EG: -
# Define a list
@arr = qw/rohit jain/;
# Define a scalar
$num = 2
# Here perl will evaluate @arr in scalar context and take its length..
# so, below code will evaluate to : - value = 2 / 2
$value = @arr / $num;
# Here since it is used with a foreach loop, @arr will be taken as in list context
foreach (@arr) {
say $_;
}
# Above foreach loop will output: - `rohit` \n `jain` to the console..
答案 3 :(得分:1)
您可以通过以下方式强制输入类型:
use Scalar::Util qw(dualvar);
use constant NOTIFY_DIE_MAIL_SEND_FAILED => dualvar 3, 'NOTIFY_DIE_MAIL_SEND_FAILED';
say NOTIFY_DIE_MAIL_SEND_FAILED;
say int(NOTIFY_DIE_MAIL_SEND_FAILED);
<强>输出:强>
NOTIFY_DIE_MAIL_SEND_FAILED
3
答案 4 :(得分:1)
在这种情况下Perl如何知道,退出需要一个数字参数?
退出期望一个数字作为其规范的一部分,如果你传递一个非整数值,它的行为有点未定义(即你不应该这样做。
现在,在这种特殊情况下, dualvar 如何根据上下文设置返回值类型?
我不知道Scalar :: Util的 dualvar 是如何实现的,但你可以用overload编写类似的内容。
您当然可以修改受祝福对象的行为:
#!/usr/bin/env perl
use strict;
use warnings;
{package Dualvar;
use overload
fallback => 1,
'0+' => sub { $_[0]->{INT_VAL} },
'""' => sub { $_[0]->{STR_VAL} };
sub new {
my $class = shift;
my $self = { INT_VAL => shift, STR_VAL => shift };
bless($self,$class);
}
1;
}
my $x = Dualvar->new(31,'Therty-One');
print $x . " + One = ",$x + 1,"\n"; # Therty-One + One = 32
从文档中,似乎重载实际上改变了声明范围内的行为,因此您应该能够在本地更改任何操作数的某些公共运算符的行为。
如果退出确实使用其中一个可重载操作将其参数计算为整数,那么此解决方案就可以。
我没有看到为子程序的参数定义数据类型的方法,就像在Java中一样?
正如其他人已经说过的那样......在Perl中并非如此,至少在编译时不是这样,除了子例程prototypes,但是它们没有提供太多的类型粒度(比如int vs strings或者不同)对象类)。
Richard已经提到了一些你可能会使用的运行时替代品。如果您不介意性能损失,我个人会推荐 Moose 。
答案 5 :(得分:0)
Rohit Jain所说的是正确的。希望输入遵循某些规则的函数只需要明确检查输入是否有效。
例如
sub foo
{
my ($param1,$param2) = shift;
$param1 =~ /^\d+$/ or die "Parameter 1 must be a positive integer.";
$param2 =~ /^(bar|baz)$/ or die "Parameter 2 must be either 'bar' or 'baz'";
...
}
这可能看起来很痛苦,但是: