perl - Perl 散列名称(在声明时)可以在同一个散列中使用吗?

标签 perl data-structures hash cgi perl-hash

我正在声明一个散列,在声明它的时候,我在内部使用它作为它的一个元素作为其他元素的输入。您可以通过以下未编译的代码轻松掌握,因为 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 (using use vars, or our) even when using the strict 'vars' pragma. Don’t lexicalize them with my $a or my $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/

相关文章:

linux - 如何在命令中写命令

perl - 如何使用 perl 获取文件创建时间和当前时间的时间差(以小时为单位)

c - getpwnam getpwnam_r

ruby - 在 Ruby 哈希中查找保留重复项

ruby - 无法将 2 个数组组合成一个散列 - ruby

perl - Perl 的 Slurp 模块如何工作?

html - 如何使用 MediaWiki::DumpFile 将维基百科 XML 转储转换为 HTML?

algorithm - 可以检查位集子集的类似 Map<bitset,object> 的数据结构?

performance - 将 Trie 编码为文件以避免重建

c++ - 将唯一的 int 数组映射到范围 0..n 的索引的哈希函数