我正在声明一个散列,在声明它的时候,我在内部使用它作为它的一个元素作为其他元素的输入。您可以通过以下未编译的代码轻松掌握,因为 Strict pragma 为 ON:
my %cob = (
'a' => 0,
'b' => 0,
'z' => sub {
my ($a, $b) = ($cob{'a'}, $cob{'b'});
return ($a+$b+1);
}
);
它会产生编译时错误。
所以我的问题是如何在声明时重用相同的散列元素作为相同散列的其他元素的输入?这里元素 'a' 和 'b' 是 'z' 元素函数的输入。
从逻辑上讲,如果尚未声明散列,则无法使用它,那么如何在声明时使用一个元素作为同一散列的其他元素的输入?希望我清楚...
最佳答案
考虑在 lexical closure 中创建共享的 $aa
和 $bb
变量生成新的 cob 哈希。
sub make_cob {
my($aa,$bb) = (0, 0);
{ a => \$aa,
b => \$bb,
z => sub { $aa + $bb + 1 },
};
}
变量名 $aa
和 $bb
避免了 perlvar documentation on $a
and $b
中的警告如果您需要在 make_cob
中执行任何排序:
$a
$b
Special package variables when using sort. Because of this specialness$a
and$b
don’t need to be declared (usinguse vars
, orour
) even when using thestrict 'vars'
pragma. Don’t lexicalize them withmy $a
ormy $b
if you want to be able to use them in the sort comparison block or function.
将一个用作普通哈希 %cob
看起来像
my %cob = %{ make_cob() };
${$cob{a}} = 10;
${$cob{b}} = 20;
print "z: ", $cob{z}(), "\n";
作为哈希引用$cob
,代码为
my $cob = make_cob;
${$cob->{a}} = 30;
${$cob->{b}} = 40;
print "z: ", $cob->{z}(), "\n";
您可以将它们全部包装在匿名订阅中,如
sub make_cob {
my($aa,$bb) = (0, 0);
{ a => sub { if (@_) { $aa = shift } else { $aa } },
b => sub { if (@_) { $bb = shift } else { $bb } },
z => sub { $aa + $bb + 1 },
};
}
my $cob = make_cob;
$cob->{a}(40);
$cob->{b}(50);
print "a: ", $cob->{a}(), "\n",
"b: ", $cob->{b}(), "\n",
"z: ", $cob->{z}(), "\n";
但是如果你要解决所有这些麻烦,请将你的 cobs 实例化为 Cob 类。
package Cob;
use strict;
use warnings;
sub new {
my($class,$aa,$bb) = @_;
$_ = defined $_ ? $_ : 0 for $aa, $bb;
bless { a => $aa, b => $bb } => $class;
}
sub a { $_[0]->{a} }
sub b { $_[0]->{b} }
sub z { $_[0]->a + $_[0]->b + 1 }
1;
用这门课练习
#! /usr/bin/env perl
use strict;
use warnings;
use Cob;
my $cob = Cob->new(1,2);
print "a: ", $cob->a, "\n",
"b: ", $cob->b, "\n",
"z: ", $cob->z, "\n";
输出:
a: 1 b: 2 z: 4
关于perl - Perl 散列名称(在声明时)可以在同一个散列中使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55667929/