我试图在两个数组上运行array_diff。
sub array_diff(\@\@) {
my %e = map { $_ => undef } @{$_[1]};
return @{[
( grep { (exists $e{$_}) ? ( delete $e{$_} ) : ( 1 ) } @{ $_[0] } ),
keys %e
] };
}
my $col = 'col';
my $stg = 'stg';
my @blocks = qw( block1 block2 block3 block4 block5 );
my %hash; @{$hash{$col}{$stg}} = qw( block1 block2 block3 );
my @diff = array_diff(@all_blocks, @{$hash{$col}{$stg}});
print ("diff : @diff\n");
当执行上面一行时,它给我以下错误。
Possible unintended interpolation of @diff in string at get_blocks.pl line 56.
Type of arg 2 to main::array_diff must be array (not reference constructor) at get_blocks.pl line 55, near "})"
syntax error at get_blocks.pl line 55, near "})"
Execution of get_blocks.pl aborted due to compilation errors.
然而当我尝试在没有数组的情况下运行同样的错误时,它却能正常工作。
my @a = qw( a b c d e);
my @b = qw( c d );
sub array_diff(\@\@) {
my %e = map { $_ => undef } @{$_[1]};
return @{[
( grep { (exists $e{$_}) ? ( delete $e{$_} ) : ( 1 ) } @{ $_[0] } ),
keys %e
] };
}
# symmetric difference
my @diff = array_diff(@a, @b);
print ("diff : @diff\n");
结果:我试图在两个数组上运行array_diff。
diff : a b e
我们可以参考 霹雳火 来找出错误和警告。
Possible unintended interpolation of @diff in string at get_blocks.pl line 56.
W模棱两可)你在双引号字符串中说了类似'@foo'这样的话,但当时范围内没有数组@foo。如果你想要一个字面的@foo,那么就把它写为
\@foo
否则就会发现你丢失的数组是怎么回事。
你正在做的是 "@diff"
不过 @diff
未声明。
Type of arg 2 to main::array_diff must be array (not reference constructor) at get_blocks.pl line 55, near "})"
(F) 该函数要求该位置的参数必须是某种类型。数组必须是@NAME或@{EXPR}。. 哈希值必须是%NAME或%{EXPR}。. 不允许隐式注销--使用{EXPR}形式作为显式注销。参见 perlref。
就像它说的那样 \@
原型必须取一个数组,而不是引用。
# Bad
array_diff([1,2,3], [4,5,6]);
# Good
array_diff(@{[1,2,3]}, @{[4,5,6]});
你的示例代码和你的错误不匹配。@diff
的声明,而你已经去掉了对 $hash{$col}{$stg}
.
我建议不要使用原型。它们不像在其他语言中声明一个函数的参数一样,而是用来模拟内置函数的神奇行为。相反,它们是用来模拟内置函数的神奇行为的。
取而代之的是传递引用。
my @diff = array_diff(\@all_blocks, $hash{$col}{$stg});
真正的子程序签名 遗憾的是还在试验阶段。
没有必要 婴儿车司机 @{[]}
左右 grep
. grep
已经返回了一个新的数组,没有必要再去克隆它。这样会使代码复杂化,浪费内存。