我必须执行将作为标量和数组工作的函数。例如:
@t = testfunc(1, 2, 3, 4);
$x = testfunc(1, 2, 3, 4);
有人知道我该怎么做吗? 它必须打印"标量"如果它是$ x并且打印"数组"如果@t。我试着做这样的事情:
sub testfunc()
{
print "test";
}
但即使这样也行不通:/
答案 0 :(得分:4)
此功能名为“呼叫上下文”。使用wantarray关键字。
@t = testfunc(1, 2, 3, 4);
$x = testfunc(1, 2, 3, 4);
sub testfunc {
if ( wantarray ) {
print "List context\n";
}
# False, but defined
elsif ( defined wantarray ) {
print "Scalar context\n";
}
# False and undefined
else {
print "Void context\n";
}
}
答案 1 :(得分:4)
perl中有一个名为wantarray
的函数返回:
true
如果在列表上下文中调用子false
如果标量undef
如果两者都没有。举个例子:
use strict;
use warnings;
sub wantarray_test {
if ( not defined wantarray() ) {
print "Called in void context by ", caller(), "\n";
}
else {
if ( wantarray() ) {
print "Called in list context by ", caller(), "\n";
return ( "A", "list", "of", "results" );
}
else {
print "called in a scalar context by ", caller(), "\n";
return "scalar result";
}
}
}
my @result = wantarray_test();
print "@result\n";
my $result = wantarray_test();
print $result, "\n";
wantarray_test();
奖金问题:
如果你认为你会得到什么:
print wantarray_test();
如果你倾向于Contextual::Return
,你可以做更多的事情 - 这将允许你测试更详细的背景,例如scalar
和boolean
之间的差异。 (这很有用,例如,如果你想测试一个百分比 - 你可能不想把'0'视为'假')。
但请注意上下文敏感的功能。构建一些意想不到的行为很容易,这可能会让你严重受挫。
作为相关说明 - 您不应该按照您的方式声明您的子。 perl中有一种称为原型的机制,用于定义子例程所期望的参数类型。见:perlsub
。您不应将sub定义为:
sub testfunc()
{
# some stuff
}
这指定了一个原型,应该避免,除非你确定这是你想要的。
答案 2 :(得分:2)
使用wantarray功能
#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';
say my $x = testfunc(1,2,3,4);
say my @x = testfunc(1,2,3,4);
sub testfunc {
return wantarray ? @_ : "@_";
}
答案 3 :(得分:1)
奇怪命名的wantarray
是标准方法 - 它可以让你区分列表和标量上下文。您还可以使用CPAN中的Want
,它比标准的wantarray
内置函数更进一步(请参阅Want
documentation)。
以下内容应返回与wantarray
解决方案相同的结果:
use Want;
sub testfuncadelic {
if (want('LIST')) {
rreturn @_; }
elsif (want('SCALAR')) {
rreturn "@_" ; }
return
}
以下内容应该剪切并粘贴到shell中作为伪 - " oneliner" (Unix语法)来演示:
% cpanm Want
% perl -MWant -E '
sub testfunc {
if (want("LIST")) {
rreturn "array in list context ", @_;}
elsif (want("SCALAR")) {
rreturn "string in scalar context @_"; }
return }
$result = testfunc(qw/1 2 3 4/ ); say $result;
@results = testfunc(qw/1 2 3 4/ ); say @results;'
<强>输出强>
string in scalar context 1 2 3 4
array in list context 1234
修改强>
@Sobrique在这里对标准方法有最彻底的处理 - 如果我问过这个问题,他/她会接受我的接受。我忽略的一件事是(显然,&#39; doh!)如果wantarray
是undef
那么你就有了无效的背景!也许我假设这个并没有意识到它可以被明确地用于检测void contxt。因此wantarray
可以为您提供所有三个标准调用上下文。另一方面,Wanted
是关于棘手的有趣的东西,我并不是故意暗示它应该用{em>代替 wantarray
。我仍然认为wantarray
应该有一个更好的名字: - )