2

我正在声明一个哈希,并且在声明它的时候,我在内部使用它作为它的一个元素作为另一个元素的输入。您可以通过以下未编译的代码轻松掌握,因为 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”元素函数的输入。

从逻辑上讲,如果尚未声明散列,则不能使用它,那么如何在声明时将一个元素用作相同散列的其他元素的输入?希望我清楚...

4

2 回答 2

4

考虑在词法闭包中创建共享变量$aa$bb变量以生成新的 cob 哈希。

sub make_cob {
  my($aa,$bb) = (0, 0);
  { a => \$aa,
    b => \$bb,
    z => sub { $aa + $bb + 1 },
  };
}

变量名称$aa并避免在perlvar 文档$bb中出现警告,以防您需要在以下位置执行任何排序:$a$bmake_cob

  • $a
  • $b
    使用sort时的特殊包变量。由于这种特殊性$a,即使在使用pragma$b时也不需要声明(使用use vars, 或) 。如果您希望能够在排序比较块或函数中使用它们,请不要将它们词汇化。ourstrict 'vars'my $amy $b

使用一个作为普通哈希%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";

但是,如果您要解决所有这些麻烦,请将您的 cob 实例化为 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";

输出:

一个:1
乙:2
z: 4
于 2019-04-14T00:34:20.383 回答
2
my ($a, $b) = ($cob{'a'}, $cob{'b'});

为了让 Perl编译这个语句,%cob必须在语句之前的某个地方声明,但%cob还没有被声明(因为它是语句的一部分)。解决方法是在声明%cob之前声明:

my %cob;   # declare the variable first
%cob = (
        'a' => 0,
        'b' => 0,
        'z' => sub {
                    my ($a, $b) = ($cob{'a'}, $cob{'b'});  # now %cob is known to be a hash
                    return ($a+$b+1);
                }                                       
    );
于 2019-04-13T20:29:20.997 回答