是否可以在Perl中增加标量引用?

ND *_*eek 3 perl pass-by-reference

假设我有一个数字,$x = 0;我想用子程序递增它,但子程序不会返回它的值:

sub increment {
    my ($var) = @_;

    my @list = (
        'a',
        'b',
        'c',

        ...

        'x',
        'y',
        'z'
    );

    return $list[$var++];
}

while ($x < 10) {
    print increment($x);
}
Run Code Online (Sandbox Code Playgroud)

原样,这将aaaaaaaaaa永远打印而不是abcdefghij.如果我替换increment($x)increment(\$x),它会将标量地址转换为十进制数,然后将其递增.在上面的场景中,它最终会抛出一个错误,因为25423331或其他任何不是有效的数组元素.

如果$ x是散列或数组中的元素,我可以传递父作为引用以使原始修改:

$x = {'val' => 0};
while ($x->{'val'} < 10) {
    print increment($x);
}

sub increment {
    ...
    return $list[$var->{$val}++];
}
Run Code Online (Sandbox Code Playgroud)

如何修改标量参考的原始值?

ike*_*ami 6

您可以传递对要修改的变量的引用.

sub increment {
    my ($ref) = @_;
    ++$$ref;
}

my $i = 0;
say $i;  # prints 0
increment(\$i);
say $i;  # prints 1
Run Code Online (Sandbox Code Playgroud)

您还可以利用Perl 通过引用传递的事实.

sub increment {
    ++$_[0];
}

my $i = 0;
say $i;  # prints 0
increment($i);
say $i;  # prints 1
Run Code Online (Sandbox Code Playgroud)

但是隐藏增量是一个非常糟糕的主意.迭代列表,

for my $x ('a'..'z') {
   ...
}
Run Code Online (Sandbox Code Playgroud)

或者写一个迭代器.

sub make_iter {
   my @list = 'a'..'z';
   return sub {
      return @list ? () : shift(@list);
   };
}

my $iter = make_iter();
while (my ($x) = $iter->()) {
   ...
}
Run Code Online (Sandbox Code Playgroud)