列表和数组有什么区别?

tem*_*ame 11 arrays perl list

页面上,它显示了如何初始化数组,如果向下滚动一下,在"列表"部分下面,它"解释"列表是什么以及它们与数组的不同之处.

除了它使用的例子与声明数组完全相同,并且不解释它.

有什么不同?

rai*_*7ow 8

实际上,这个问题在Perl的FAQ中得到了很好的回答.列表是(一种)组织Perl源代码中的数据的方法.数组是一种存储数据; 哈希是另一个.

这里的区别非常明显:

my @arr = (4, 3, 2, 1);
my $arr_count  = @arr;
my $list_count = (4, 3, 2, 1);

print $arr_count, "\n"; # 4
print $list_count;      # 1
Run Code Online (Sandbox Code Playgroud)

乍一看,这里有两个相同的列表.但请注意,只有@arr通过标量赋值才能正确计算分配给变量的那个.该$list_count门店1 -评估与表达的结果,comma运营商(这基本上使我们在列举的最后一个表达式- 1).

请注意,列表运算符/函数与数组之间存在轻微(但非常重要)的区别:前者是一种杂食,因为它们不会更改源数据,后者则不会.例如,您可以安全地切片并加入您的列表,如下所示:

print join ':', (4,2,3,1)[1,2]; 
Run Code Online (Sandbox Code Playgroud)

...但是试图"弹出"它会给你一个很有说服力的信息:

pop (4, 3, 2, 1);
### Type of arg 1 to pop must be array (not list)...
Run Code Online (Sandbox Code Playgroud)

  • @aerovistae不,他们显然不是一回事.列表和数组的行为可能完全不同(如上所述),并且掌握差异对于编写非错误的Perl至关重要. (4认同)
  • 谈论列表计数是无意义和误导的.我不赞成. (3认同)
  • @Aerovistae:数组和列表不再是标量变量和字符串或数字的"相同的东西". (3认同)
  • 你的最后一个例子存在严重缺陷.将`4`更改为`$ x`并且没有错误(在5.16中).您的示例未显示您声称的内容. (2认同)

ike*_*ami 8

数组是一种变量.它包含0个或多个由非负整数键和标量值组成的元素.例如,

my @a;
Run Code Online (Sandbox Code Playgroud)

作为变量,您可以操纵数组.您可以添加元素,更改元素的值等.


"列表"意味着很多东西.它的两个主要用途是引用列表值和列表运算符.

列表值是堆栈上零个或多个标量的有序集合.例如,以下代码中的sub返回要分配给@a(数组)的列表.

my @a = f();
Run Code Online (Sandbox Code Playgroud)

列表值无法操纵; 它们被任何经过它们的操作员全部吸收.它们就是如何在子和运算符之间传递值.


list运算符是一个N-ary运算符*,它依次计算每个操作数.在列表上下文中,列表运算符返回一个列表,该列表包含由其操作数返回的列表的合并.例如,以下列表运算符返回包含数组的所有元素的列表值,@a并且,:

my @c = ( @a, @b );
Run Code Online (Sandbox Code Playgroud)

(顺便说一下,parens不会创建列表.它们只是覆盖优先级.)

你不能操纵列表操作符,因为它是代码.


* - 文档说这是一个二元运算符(至少在标量上下文中),但事实并非如此.


Bor*_*din 8

看看perldoc -q "list and an array".最大的区别是数组是一个变量,但Perl的所有数据类型(标量,数组和散列)都可以提供一个列表,它只是一组有序的标量.

考虑这段代码

use strict;
use warnings;

my $scalar = 'text';
my @array = (1, 2, 3);
my %hash = (key1 => 'val1', key2 => 'val2');

test();
test($scalar);
test(@array);
test(%hash);

sub test { printf "( %s )\n", join ', ', @_ }
Run Code Online (Sandbox Code Playgroud)

输出这个

(  )
( text )
( 1, 2, 3 )
( key2, val2, key1, val1 )
Run Code Online (Sandbox Code Playgroud)

Perl子例程将列表作为其参数.在第一种情况下,列表为空; 在第二个它有一个单一元素( $scalar); 在第三个列表中,列表的大小@array和包含的大小相同( $array[0], $array[1], $array[2], ...),并且在最后一个列表中,它是错误的两倍%hash,并且包含( 'key1', $hash{key1}, 'key2', $hash{key2}, ...).

显然,可以在几个方面,包括标量变量,常量标量的混合,和子程序调用的结果,如提供该名单

test($scalar, $array[1], $hash{key2}, 99, {aa => 1, bb => 2}, \*STDOUT, test2())
Run Code Online (Sandbox Code Playgroud)

我希望很明显这样的列表与数组非常不同.

将数组视为列表变量会有帮助吗?标量文字和标量变量之间很少有区别.例如:

my $str = 'string';
my $num = 99;
Run Code Online (Sandbox Code Playgroud)

很明显,'string'并且99是文字,$str而且$num是变量.这里的区别是一样的:

my @numbers = (1, 2, 3, 4);
my @strings = qw/ aa bb cc dd /;
Run Code Online (Sandbox Code Playgroud)

where (1, 2, 3, 4)qw/ aa bb cc dd /是list literals,while @numbers@strings是变量.

  • 天啊,这是虫子的两倍! (4认同)