Arrays 原型:返回数组或标量

Arrays 原型:返回数组或标量,arrays,perl,reference,return-value,perl-data-structures,Arrays,Perl,Reference,Return Value,Perl Data Structures,我很难理解如何使用子例程原型返回数组。 这里有一个例子 sub f (&@) { my ($func) = @_; eval &$func; } my $a = f {return 1}; my @b = f {return (2,1,1,4)}; print "a = ".$a."\n"; print "b = ".scalar(@b)."\n"; 这将输出a=1和b=1,但我希望@b的长度为4 我还尝试返回函数f中的引用\

我很难理解如何使用子例程原型返回数组。 这里有一个例子

sub f (&@) {
        my ($func) = @_;        
        eval &$func;
}

my $a = f {return 1};
my @b = f {return (2,1,1,4)};

print "a = ".$a."\n";
print "b = ".scalar(@b)."\n";
这将输出
a=1
b=1
,但我希望
@b
的长度为4


我还尝试返回函数
f
中的引用
\eval&$func
。然后,我可以取消对标量的引用(
$$a
是1),但是当取消对数组的引用(
@$b
)时,perl告诉我它不是数组引用。

无需求值,您可以

use warnings;
sub f (&) {
    my ($func) = @_;
    $func->(); # better than &$func
}
另一方面,
eval
只返回由
$f
给出的列表中的最后一个元素,因为它与写入
eval scalar$func->()相同
,因此
@b
以一个元素=>
4

EXPR的返回值被解析和执行,就像它是一个小Perl程序一样。首先解析表达式的值(它本身在标量上下文中确定),如果没有错误,则在当前Perl程序的词法上下文中作为块执行

sub f (&) {
    my ($func) = @_;
    eval { &$func }
}

不需要评估,你可以

use warnings;
sub f (&) {
    my ($func) = @_;
    $func->(); # better than &$func
}
另一方面,
eval
只返回由
$f
给出的列表中的最后一个元素,因为它与写入
eval scalar$func->()相同
,因此
@b
以一个元素=>
4

EXPR的返回值被解析和执行,就像它是一个小Perl程序一样。首先解析表达式的值(它本身在标量上下文中确定),如果没有错误,则在当前Perl程序的词法上下文中作为块执行

sub f (&) {
    my ($func) = @_;
    eval { &$func }
}

原型对子例程返回标量还是列表没有影响。如果您想知道在什么上下文中调用了子例程,请使用

eval &$func;
上面的行首先在标量上下文中调用
$func
引用的子例程,然后将其返回值转换为字符串,并将该字符串作为Perl程序执行

sub f (&) {
    my ($func) = @_;
    eval { &$func }
}
这将执行您显然想要的操作(在
eval
块中调用
f
本身被调用的相同上下文(标量或列表)中调用
$func
引用的子例程以捕获运行时错误)


这是一种更现代的风格,带有
->
操作符。

原型对子例程返回标量还是列表没有影响。如果您想知道在什么上下文中调用了子例程,请使用

eval &$func;
上面的行首先在标量上下文中调用
$func
引用的子例程,然后将其返回值转换为字符串,并将该字符串作为Perl程序执行

sub f (&) {
    my ($func) = @_;
    eval { &$func }
}
这将执行您显然想要的操作(在
eval
块中调用
f
本身被调用的相同上下文(标量或列表)中调用
$func
引用的子例程以捕获运行时错误)


这是一种更现代的风格,带有
->
操作符。

您可能需要添加的一个关键点是
eval&$func
将在标量上下文中调用
$func
(这就是为什么它只返回“4”),而
eval{$func->()
将从对
f()的函数调用中继承列表或标量上下文,所以应该像预期的那样工作。好吧,我不知道
$func
是在标量上下文中处理的!现在它有了意义。它很简单:
eval
需要一个字符串作为参数,因此它在标量上下文中计算其操作数。虽然
&$func()
$func->()
是等效的,
&$func
是不同的–它将使用当前的
@
作为参数调用函数。所以
f{say“@_”}1,2,3
会打印出
code(0x0123ABCD)1,2,3
@amon我从来不知道!您可能需要添加的一个关键点是,
eval&$func
将在标量上下文中调用
$func
(这就是为什么它只返回“4”),而
eval{$func->()}
将从对
f()
的函数调用中继承列表或标量上下文,因此应该按预期工作。好,我不知道
$func
是在标量上下文中处理的!现在它有了意义。它很简单:
eval
需要一个字符串作为参数,因此它在标量上下文中计算其操作数。虽然
&$func()
$func->()
是等效的,
&$func
是不同的–它将使用当前的
@
作为参数调用函数。所以
f{say“@_”}1,2,3
会打印出
code(0x0123ABCD)1,2,3
@amon我从来不知道!