在这个页面上,它展示了如何初始化一个数组,如果你向下滚动一点,在名为“列表”的部分下,它会“解释”什么是列表以及它们与数组的不同之处。
除了它使用了一个与声明数组完全相同的示例,并且没有对其进行任何解释。
有什么不同?
看看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 ', ', @_ }
输出这个
( )
( text )
( 1, 2, 3 )
( key2, val2, key1, val1 )
Perl 子例程将列表作为其参数。在第一种情况下,列表是空的;在第二个中它有一个元素( $scalar)
;在第三个中,列表的大小与@array
和 contains相同( $array[0], $array[1], $array[2], ...)
,在最后一个中,它的bug 是和 contains中元素数量的两倍。%hash
( 'key1', $hash{key1}, 'key2', $hash{key2}, ...)
很明显,该列表可以通过多种方式提供,包括标量变量、标量常量和子例程调用的结果的混合,例如
test($scalar, $array[1], $hash{key2}, 99, {aa => 1, bb => 2}, \*STDOUT, test2())
我希望很清楚这样的列表与数组有很大不同。
将数组视为列表变量会有所帮助吗?区分标量文字和标量变量很少有问题。例如:
my $str = 'string';
my $num = 99;
很明显,'string'
and99
是文字,而$str
and$num
是变量。这里的区别是一样的:
my @numbers = (1, 2, 3, 4);
my @strings = qw/ aa bb cc dd /;
其中(1, 2, 3, 4)
和qw/ aa bb cc dd /
是列表文字,而@numbers
和@strings
是变量。
实际上,这个问题在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
乍一看,这里有两个相同的列表。但是请注意,只有分配给@arr
变量的那个才能通过标量分配正确计数。$list_count
商店 1 - 使用运算符评估表达式的结果(comma
基本上为我们提供了该枚举中的最后一个表达式 - 1)。
请注意,列表运算符/函数和数组运算符/函数之间存在细微(但非常重要)的区别:前者是杂食动物,因为它们不会更改源数据,而后者则不会。例如,您可以安全地切片并加入您的列表,如下所示:
print join ':', (4,2,3,1)[1,2];
...但试图“弹出”它会给你一个很有说服力的信息:
pop (4, 3, 2, 1);
### Type of arg 1 to pop must be array (not list)...
数组是一种变量。它在单调递增的索引处包含 0 个或多个标量。例如,以下创建数组@a
:
my @a;
作为变量,您可以操作数组。您可以添加元素,更改元素的值等。
“列表”意味着很多东西。它的两个主要用途是引用列表值和列表运算符的实例。
列表值是堆栈上零个或多个标量的有序集合。例如,以下代码中的 sub 返回要分配给@a
(数组)的列表。
my @a = f();
列表值不能被操纵;它们被传递给它们的任何操作员全部吸收。它们就是在 subs 和操作符之间传递值的方式。
列表运算符 ( ,
) 是一个 N 元运算符*,它依次计算其每个操作数。在列表上下文中,列表运算符返回一个列表,该列表由其操作数返回的列表的合并组成。例如,以下代码段中的列表运算符返回由数组的所有元素组成的列表值@a
和@b
:
my @c = ( @a, @b );
(顺便说一句,parens 不会创建列表。它们只是为了覆盖优先级。)
您不能操纵列表运算符,因为它是代码。
* - 文档说它是一个二元运算符(至少在标量上下文中),但事实并非如此。
差异的简单演示。
sub getarray{ my @x = (2,4,6); return @x; }
sub getlist { return (2,4,6); }
现在,如果你这样做:
my @a = getarray();
my @b = getlist();
然后@a
和@b
都将包含相同的值 - 列表(2,4,6)
。但是,如果您这样做:
my $a = getarray();
my $b = getlist();
然后$a
将包含值 3,而$b
将包含值 6。
所以是的,您可以说数组是包含列表值的变量,但这并不能说明全部情况,因为数组和文字列表有时的行为完全不同。
列表是逗号分隔值 (csv) 或表达式 (cse)。数组(和哈希)是容器。
可以通过列表初始化数组或哈希:
@a = ("profession", "driver", "salary", "2000");
%h = ("profession", "driver", "salary", "2000");
可以返回一个列表:
sub f {
return "moscow", "tel-aviv", "madrid";
}
($t1, $t2, $t3) = f();
print "$t1 $t2 $t3\n";
($t1, $t2, $t3) 是标量容器 $t1, $t2, $t3 的列表。
列表是编写 perl 表达式的一种形式(语法的一部分),而数组是数据结构(内存位置)。
列表和数组之间的区别让很多人感到困惑。Perl 本身错误地命名了它的内置函数wantarray():“这个函数应该被命名为 wantlist() 。” perlfaq4 中有一个答案,“列表和数组有什么区别?” ,但这并没有结束我的困惑。
我现在相信这些是真的:
\(2, 4, 6)
返回对列表中标量的引用列表。您可以使用[2, 4, 6]
来引用匿名数组。(2, 4, 6)[1]
4 也是如此。但是如果我想计算列表中的元素,或者获取数组的最后一个元素怎么办?我应该以某种方式在数组和列表之间进行转换吗?
您始终可以使用语法将列表转换为数组。[...]
计算列表中元素的一种方法是创建一个匿名数组,然后立即在标量上下文中取消引用它,如下所示:
sub list { return qw(carrot stick); }
my $count = @{[list()]};
print "Count: $count\n"; # Count: 2
另一种方法是使用列表赋值运算符,如下所示:
sub list { return qw(carrot stick); }
my $count = (()=list());
print "Count: $count\n"; # Count: 2
这段代码中没有数组,但是列表赋值运算符返回被赋值的事物的数量。我将它们分配给一个空的变量列表。在代码高尔夫中,我编写()=$str=~/reg/g
来计算某个字符串中的正则表达式匹配。
您无需将数组转换为列表,因为列表上下文中的数组已经是列表。如果您想要数组的最后一个元素,只需说$array[-1]
.
逗号运算符将返回列表的最后一个元素,但我不能使用它来获取数组的最后一个元素。如果我((),@array)
在标量上下文中说,那么@array
是在标量上下文中,我得到了计数。
您无需创建数组来索引列表。您可以创建一个匿名数组,如 中[list()]->[1]
,也可以创建一个列表切片,如中(list())[1]
。我在使用列表切片时遇到了麻烦,因为它们有不同的语法。列表切片需要括号!在 C 或 Python 或 Ruby 中,func()[1]
会对函数的返回值做数组索引,但在 Perl 中,func()[1]
是语法错误。你必须说(func())[1]
。
例如,我想打印数组中第三大的数字。因为我很懒,所以我对数组进行排序并取倒数第三个元素:
my @array = (112, 101, 114, 108, 32, 104, 97, 99, 107);
print +(sort { $a <=> $b } @array)[-3], "\n"; # prints 108
一元+
防止 print() 函数窃取我的括号。
您可以在数组上使用列表切片,如(@array)[1]
. 这是有效的,因为数组是一个列表。列表和数组的区别在于数组可以做$array[1]
.
数组与列表
列表是一种不同于数组的数据结构。
最大的区别在于直接访问与顺序访问的思想。数组允许两者;直接和顺序访问,而列表只允许顺序访问。这是因为这些数据结构存储在内存中的方式。
此外,列表的结构不像数组那样支持数字索引。而且,元素不需要像数组那样在内存中彼此相邻分配。
数组
数组是项的有序集合,其中数组中的每个项都有一个索引。
但主要区别在于:
数组有一个scalar-context-value
like count of elements
。
列表有一个scalar-context-value
like LAST element in list
。
所以,你需要了解goat-operator
:=()=
。
用法?
perl -e '$s =()= qw(a b c); print $s' # uh? 3? (3 elements, array context)
perl -e '$s = qw(a b cLastElementThatYouSee); print $s' # uh? cLastElementThatYouSee? (list context, last element returned)
如您所见,=()=
将上下文更改为array