在 perl 中立即调用函数表达式(IIFE)的最佳方法?
Best way to Immediately Invoked Function Expression (IIFE) in perl?
借用术语 Javascript,Perl 中 IIFE 的 'best practice' 方法是什么?
我下面的测试代码是一个简单的循环调用匿名 sub 并立即执行它以构建一个 subs 数组(这只是 return 循环索引)。这主要是我想要的,但是我需要使用一个中间变量(而不是使用 @_,它在内部函数上发生变化)。
use warnings;
use strict;
my @funcs;
for(my $i=0;$i<3;$i++) {
sub {
my $index=shift;
$funcs[$index]=sub {$index};
}
-> ($i);
}
for (@funcs) {
print &$_()."\n";
}
#Output
0
1
2
我知道我可以使用 map
来重构这个问题。但是抛开这些,有没有更好的方法呢?
更新
感谢@ikegami 强调了一些要点。
为了以后对这个问题的看法,我对此的看法:
'iterator' for 循环与 'c style' for 循环具有不同的作用域(它是映射吗?)。这可以在根本不需要 IIFE 的情况下清理代码。甜
更新 2
以下代码显示了我所看到的差异。不是说一个比另一个好,但我认为很高兴知道。我之后的输出是 0 1 2 但第一个只重复 $i 的最后一个值(++ 运算符后的 3)。
use warnings;
use strict;
my @funcs;
print "C loop direct assignment of sub\n";
for(my $i=0;$i<3;$i++) {
$funcs[$i]= sub {$i};
}
print &$_()."\n" for @funcs;
print "C loop direct assignment of sub with variable\n";
for(my $i=0;$i<3;$i++) {
my $index=$i; #assignment/copy
$funcs[$index]= sub {$index};
}
print &$_()."\n" for @funcs;
print "For loop interator\n";
@funcs=[];
for my $i (0..2) {
$funcs[$i]=sub {$i};
}
print &$_()."\n" for @funcs;
print "C loop with IIFE assignment\n";
@funcs=[];
for (my $i=0;$i<3;$i++) {
sub {
my $index=shift;
$funcs[$index]=sub {$index};
}
-> ($i);
}
print &$_()."\n" for @funcs;
出局是:
C loop direct assignment of sub
3
3
3
C loop direct assignment of sub with variable
0
1
2
For loop interator
0
1
2
C loop with IIFE assignment
0
1
2
Perl 相当于
(function () {
var x = ...;
...
})();
是
sub {
my $x = ...;
...
}->();
也就是说,IIFE 只是一种解决方法,在 Perl 中根本不需要。
(function () {
var x = ...;
...
})();
是
的解决方法
{
my $x = ...;
...
}
和
var result = (function () {
return ...;
})();
是
的解决方法
my $result = do {
...
};
您似乎正在尝试翻译类似于以下内容的内容:
let funcs = [];
for (let i=0; i<3; ++i) {
(function() {
var index = i;
funcs.push( function() { return index; } );
})();
}
for (let func of funcs)
console.log(func());
以下为直译:
my @funcs;
for (my $i=0; $i<3; ++$i) {
sub {
my $index = $i;
push @funcs, sub { $index };
}->();
}
say $_->() for @funcs;
但是使用 IIFE 根本没有意义。一个人会简单地使用以下内容:
my @funcs;
for (my $i=0; $i<3; ++$i) {
my $index = $i;
push @funcs, sub { $index };
}
say $_->() for @funcs;
现在,人们倾向于避免在 Perl 中使用 C-style for 循环,因为使用 foreach 循环可读性更高(也更有效!)。它还使解决方案更加简单,因为 foreach 循环的循环变量的范围是循环体,而不是循环语句。
my @funcs;
for my $i (0..2) {
push @funcs, sub { $i };
}
say $_->() for @funcs;
借用术语 Javascript,Perl 中 IIFE 的 'best practice' 方法是什么?
我下面的测试代码是一个简单的循环调用匿名 sub 并立即执行它以构建一个 subs 数组(这只是 return 循环索引)。这主要是我想要的,但是我需要使用一个中间变量(而不是使用 @_,它在内部函数上发生变化)。
use warnings;
use strict;
my @funcs;
for(my $i=0;$i<3;$i++) {
sub {
my $index=shift;
$funcs[$index]=sub {$index};
}
-> ($i);
}
for (@funcs) {
print &$_()."\n";
}
#Output
0
1
2
我知道我可以使用 map
来重构这个问题。但是抛开这些,有没有更好的方法呢?
更新
感谢@ikegami 强调了一些要点。
为了以后对这个问题的看法,我对此的看法:
'iterator' for 循环与 'c style' for 循环具有不同的作用域(它是映射吗?)。这可以在根本不需要 IIFE 的情况下清理代码。甜
更新 2
以下代码显示了我所看到的差异。不是说一个比另一个好,但我认为很高兴知道。我之后的输出是 0 1 2 但第一个只重复 $i 的最后一个值(++ 运算符后的 3)。
use warnings;
use strict;
my @funcs;
print "C loop direct assignment of sub\n";
for(my $i=0;$i<3;$i++) {
$funcs[$i]= sub {$i};
}
print &$_()."\n" for @funcs;
print "C loop direct assignment of sub with variable\n";
for(my $i=0;$i<3;$i++) {
my $index=$i; #assignment/copy
$funcs[$index]= sub {$index};
}
print &$_()."\n" for @funcs;
print "For loop interator\n";
@funcs=[];
for my $i (0..2) {
$funcs[$i]=sub {$i};
}
print &$_()."\n" for @funcs;
print "C loop with IIFE assignment\n";
@funcs=[];
for (my $i=0;$i<3;$i++) {
sub {
my $index=shift;
$funcs[$index]=sub {$index};
}
-> ($i);
}
print &$_()."\n" for @funcs;
出局是:
C loop direct assignment of sub
3
3
3
C loop direct assignment of sub with variable
0
1
2
For loop interator
0
1
2
C loop with IIFE assignment
0
1
2
Perl 相当于
(function () {
var x = ...;
...
})();
是
sub {
my $x = ...;
...
}->();
也就是说,IIFE 只是一种解决方法,在 Perl 中根本不需要。
(function () {
var x = ...;
...
})();
是
的解决方法{
my $x = ...;
...
}
和
var result = (function () {
return ...;
})();
是
的解决方法my $result = do {
...
};
您似乎正在尝试翻译类似于以下内容的内容:
let funcs = [];
for (let i=0; i<3; ++i) {
(function() {
var index = i;
funcs.push( function() { return index; } );
})();
}
for (let func of funcs)
console.log(func());
以下为直译:
my @funcs;
for (my $i=0; $i<3; ++$i) {
sub {
my $index = $i;
push @funcs, sub { $index };
}->();
}
say $_->() for @funcs;
但是使用 IIFE 根本没有意义。一个人会简单地使用以下内容:
my @funcs;
for (my $i=0; $i<3; ++$i) {
my $index = $i;
push @funcs, sub { $index };
}
say $_->() for @funcs;
现在,人们倾向于避免在 Perl 中使用 C-style for 循环,因为使用 foreach 循环可读性更高(也更有效!)。它还使解决方案更加简单,因为 foreach 循环的循环变量的范围是循环体,而不是循环语句。
my @funcs;
for my $i (0..2) {
push @funcs, sub { $i };
}
say $_->() for @funcs;