Perl 中匿名数组的优点是什么?

Niz*_*zam -2 perl reference

Perl 中匿名数组的优点是什么?

bri*_*foy 8

数组引用(匿名数组是其中的一种)允许 Perl 将数组视为单个项目。这也允许您构建复杂的嵌套数据结构。这也适用于散列、代码和所有其他引用类型,但在这里我将只显示散列引用。您可以阅读Intermediate Perl了解更多信息。

对于直接的字面问题,请考虑创建数组的两种方法:使用命名变量和不使用命名变量(“匿名”):

my @named_array = ( 1, 3, 7 );

[ 1, 3, 7 ];
Run Code Online (Sandbox Code Playgroud)

第一行接受一个列表并将其存储在一个命名的数组变量中。您可能已经习惯在任何地方看到它。

第二行,[ 1, 3, 7 ],没有做任何事情。这只是一个值。

但是,考虑一下这个模拟,你将一个标量值存储在一个标量变量中(在那里重载了“标量”的使用),下一行就是这个值:

my $number = 6;

6;
Run Code Online (Sandbox Code Playgroud)

现在是诀窍。您知道可以将标量变量传递给子例程。你可以这样写:

my $number = 6;
some_sub( $number );
Run Code Online (Sandbox Code Playgroud)

但是,如果这是它的唯一用途,为什么还要为变量烦恼呢?完全摆脱它并直接传递值:

some_sub( 6 );
Run Code Online (Sandbox Code Playgroud)

匿名引用也是一样。您可以先制作命名版本并引用它:

my @array = ( 1, 3, 7 );
some_sub( \@array );
Run Code Online (Sandbox Code Playgroud)

但就像标量示例一样,如果命名数组只是为了获得对它的引用,则不需要用命名数组来混淆代码。直接做参考即可:

some_sub( [ 1, 3, 7 ] );
Run Code Online (Sandbox Code Playgroud)

但是这个故事还有更多内容,您必须稍微了解 Perl 的工作原理才能理解它。

为什么要引用?

Perl 主要围绕标量(单个项目)和列表(多个项目)构建。标量变量保存标量值,数组变量保存列表(请参阅列表和数组之间的区别是什么?)。

有许多功能只能使用标量,包括单个列表元素、散列键和散列值:

$array[$i] = $single_item;
$hash{$single_item} = $other_single_item;
Run Code Online (Sandbox Code Playgroud)

其他始终是列表的地方,例如子程序的参数列表:

sub some_sub {
    my @args = @_;
    ...
    }
Run Code Online (Sandbox Code Playgroud)

即使你some_sub用两个数组调用,你最终也会得到一个存储在@_. 你不知道在哪里@array_1停止和@array_2开始。这是一个列表,其大小是两个数组的组合大小:

some_sub( @array_1, @array_2 );
Run Code Online (Sandbox Code Playgroud)

引用是一种将某物视为单个项目的方法。当您获得该单个项目时,您可以取消对它的引用以恢复到原始状态。

这意味着您可以将数组引用存储为哈希值:

$hash{$key} = \@some_array; # ref to named variable
$hash{$key} = [ 1, 3, 7 ];  # anonymous array directly
Run Code Online (Sandbox Code Playgroud)

或者,您可以创建一个列表,其中每个项目都是一个数组引用,而不是您之前看到的单个“平面”列表:

my @Array_of_Arrays = ( \@array_1, \@array_2 , [1,3,7], ... );
my $seventh_of_ninth = $Array_of_Arrays[9][7];
Run Code Online (Sandbox Code Playgroud)

Perl数据结构食谱(perldsc)有不同的种类,您建立与引用复杂的数据结构的例子很多。

您可以传递对子例程的引用,这样数组元素就不会混合。这个参数列表正好是两个元素,在子程序中你知道你正在处理哪个数组:

some_sub( \@array_1, \@array_2 );
Run Code Online (Sandbox Code Playgroud)

如果您对此的另一个方面感到好奇,可以更新您的问题。