1

传递给函数时如何取消引用数组数组?

我这样做是这样的:

my @a = {\@array1, \@array2, \@array3};

func(\@a);


func{
    @b = @_;

    @c = @{@b};
}

实际上我希望数组@c应该包含@array1@array2和的地址@array3

4

5 回答 5

8
my @a = {\@array1, \@array2, \@array3};

上面是一个具有单个成员的数组 -> 一个包含以下内容的哈希

{ ''.\@array1 => \@array2, ''.\@array3 => undef }

因为作为散列中的键,Perl 将引用强制@array1转换为字符串。Perl 允许将标量哈希引用分配给数组,因为“理解”您想要一个数组,其中第一个元素是您分配给它的标量。

您创建一个数组数组,如下所示:

my @a = (\@array1, \@array2, \@array3);

然后在您的函数中,您将解压缩它们,如下所示:

sub func {
    my $ref = shift;
    foreach my $arr ( @$ref ) {
        my @list_of_values = @$arr;
    }
}

或者它的一些变体,比如说地图是最简单的表达方式:

my @list_of_entries = map { @$_ } @$ref;

在您的示例中,@c地址列表与正确构造的@a.

于 2010-10-13T15:06:23.427 回答
5

您可能想阅读perldoc perlreftut, perldoc perlref,并且perldoc perldsc 您可以说:

sub func {
    my $arrayref = shift;

    for my $aref (@$arrayref) {
        print join(", ", @$aref), "\n";
    }
}

my @array1 = (1, 2, 3);
my @array2 = (4, 5, 6);
my @array3 = (7, 8, 9);

my @a = \(@array1, @array2, @array3);

func \@a;

或更简洁:

sub func {
    my $arrayref = shift;

    for my $aref (@$arrayref) {
        print join(", ", @$aref), "\n";
    }
}

func [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ];
于 2010-10-13T15:07:45.570 回答
0

阅读perlreftut文档。

编辑:其他人指出了我一开始错过的一个好点。在@a 的初始化中,您的意思可能是@a = (...)(创建包含引用的数组)或$arrayref = [...](创建对数组的引用),而不是{...}(创建对哈希的引用)。这篇文章的其余部分假装你有这个@a = (...)版本。

由于您将一个参数(对 的引用@a)传递给func,因此 @_ 是一个包含该引用的列表。您可以获取该引用,然后通过执行以下操作取消引用它:

sub func {
  my $arrayref = shift;
  my @c = @{$arrayref};
}

或者在一行中,它看起来像:

sub func {
  my @c = @{shift()};
}

(如果您没有在 中使用反斜杠func(\@a),@_ 将等于@a,即三个引用的数组。)

于 2010-10-13T15:07:06.040 回答
0

以下函数旨在获取数组或数组引用,并返回一个唯一值的排序数组。未定义的值被删除,HASH 和 GLOB 保持原样。

#!/usr/bin/perl
use strict; use warnings;

my @one = qw / dog rat / ;
my @two = qw / dog mice / ;
my @tre = ( "And then they said it!", "No!??  ", );
open my $H, '<', $0 or die "unable to open $0 to read";
my $dog; # to show behavior with undefined value
my %hash; $hash{pig}{mouse}=55; # to show that it leaves HASH alone
my $rgx = '(?is)dog'; $rgx = qr/$rgx/; # included for kicks

my @whoo =  (
    'hey!',
    $dog, # undefined
    $rgx,
    1, 2, 99, 999, 55.5, 3.1415926535,
    %hash,
    $H,
    [ 1, 2, 
              [ 99, 55, \@tre, ],
    3, ],
        \@one, \@two,
        [ 'fee', 'fie,' ,
            [ 'dog', 'dog', 'mice', 'gopher', 'piranha', ],
            [ 'dog', 'dog', 'mice', 'gopher', 'piranha', ],
        ],
        [ 1, [ 1, 2222, ['no!', 'no...', 55, ], ], ],
        [ [ [ 'Rat!', [ 'Non,', 'Tu es un rat!' , ], ], ], ], 
        'Hey!!',
        0.0_1_0_1,
        -33,
);


print join ( "\n", 
    recursively_dereference_sort_unique_array( [ 55, 9.000005555, ], @whoo, \@one, \@whoo, [ $H ], ),
    "\n", );
close $H;
exit;

sub recursively_dereference_sort_unique_array
{
    # recursively dereference array of arrays; return unique values sorted. Leave HASH and GLOB (filehandles) as they are.
    # 2020v10v04vSunv12h20m15s
    my $sb_name = (caller(0))[3];
    @_ = grep defined, @_; #https://stackoverflow.com/questions/11122977/how-do-i-remove-all-undefs-from-array
    my @redy = grep { !/^ARRAY\x28\w+\x29$/ } @_; # redy==the subset that is "ready"
    my @noty = grep {  /^ARRAY\x28\w+\x29$/ } @_; # noty==the subset that is "not yet"
    my $countiter = 0;
    while (1)
    {
        $countiter++; 
        die "$sb_name: are you in an infinite loop?" if ($countiter > 99);
        my @next;
        foreach my $refarray ( @noty )
        {
            my @tmparray = @$refarray;
            push    @next, @tmparray;
        }
        @next = grep defined, @next;
        my @okay= grep { !/^ARRAY\x28\w+\x29$/ } @next;
        @noty   = grep {  /^ARRAY\x28\w+\x29$/ } @next;
        push @redy, @okay;
        my %hash = map { $_ => 1 } @redy; # trick to get unique values
        @redy    = sort keys %hash;
        return @redy unless (scalar @noty);
    }
}

于 2020-10-04T21:08:48.253 回答
-1

应该

func {
    $b = shift;
}

如果您要传递参考。希望对一些人有所帮助。

于 2010-10-13T15:04:34.907 回答