为什么函数的引用作为SCALAR返回

vir*_*rus 2 perl

我无法理解,如果我取消注释返回行,那么输出将是"CODE",否则"SCALAR"..为什么会这样?

use strict;
sub test {
        my ($abc,$grab) = @_;
        print 'i m here';
        print $abc;
        ## return [];   if uncommented then output will be "REF" else "SCALAR"
}

my $pass= "i m good";
my %my_hash = ();
$my_hash{'fun'} = \&test($pass);
print ref($my_hash{'fun'})
Run Code Online (Sandbox Code Playgroud)

Sin*_*nür 5

您没有参考函数.

当你写:

\&test($pass);
Run Code Online (Sandbox Code Playgroud)

这是一个函数调用(你有一个参数列表).

因此,test使用参数调用该函数$pass,然后引用返回的值(&除非您知道并特别希望它执行的操作,否则不应为函数调用添加前缀).

如果你想要引用test,你应该使用

$my_hash{'fun'} = \&test; ### (1)
Run Code Online (Sandbox Code Playgroud)

如果要引用test使用当前范围内的参数调用的函数,$pass则应使用:

$my_hash{'fun'} = sub { test($pass) }; ### (2)
Run Code Online (Sandbox Code Playgroud)

请注意,后者将在当前的范围变量中创建一个闭包$pass.要调用(1),请使用$my_hash{fun}->($some_arg).要调用(2),请使用$my_hash{fun}->().


cho*_*oba 5

在没有隐式的情况下return,子例程返回最后一个表达式的值.print成功时返回1,即标量.

\&test($pass)是相同的\ test($pass),即它评估对sub返回的值的引用test.如果它返回1 print,你将获得SCALAR,如果它返回[],你将获得REF,因为你有一个对数组的引用的引用.您也可以通过解除引用来验证它:

print ${ $my_hash{fun} }, ': ', ref $my_hash{fun}, "\n";
Run Code Online (Sandbox Code Playgroud)

  • @virus:请理解`ref \&test`和`ref \&test()`之间的区别. (3认同)