但它使用的例子与声明数组完全相同,根本没有解释。
两者有什么区别?
请查看perldoc -q "列表和数组"
。最大的区别是数组是一个变量,但是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的大小相同,并包含($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())
我希望你能明白,这样的列表和数组是非常不同的。
把数组看作是列表变量,这样有帮助吗?通常很容易区分标量字面量和标量变量。例如:
my $str = 'string';
my $num = 99;
很明显,'string'
和99
是字面值,而$str
和$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常见问题解答中已经有很好的回答。列表是组织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-使用逗号
运算符计算表达式的结果(基本上给我们枚举中的最后一个表达式-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)...
4
更改为$x
,则不会出现错误(在5.16中)。你的例子并没有展示你所声称的内容。 - ikegami数组是一种变量类型。它包含0个或多个标量,这些标量的索引单调递增。例如,以下代码创建了一个名为@a
的数组:
my @a;
@a
(一个数组)。my @a = f();
列表值无法被操作; 它们被传递给任何运算符时整个地吸收。它们只是在子程序和运算符之间传递值的方式。
列表运算符(,
)是一个N元运算符*,按顺序评估它的每个操作数。在列表上下文中,列表运算符返回一个列表,包含其操作数返回的列表的合并。例如,以下代码片段中的列表运算符返回一个列表值,其中包含数组@a
和@b
的所有元素:
my @c = ( @a, @b );
顺便提一下,括号并不创建列表。它们只是为了覆盖优先级。
由于其是代码,因此您无法操作列表运算符。
* ——文档中说它是二进制运算符(至少在标量上下文中),但这是不正确的。
(1, 2)
或 ("key" => "value", "key2" => "value2")
。我不确定我的观点是什么了。叹气。Perl 是不同的。 - temporary_user_name@a = (1,2,7); $b = @a;
将导致 $b
是 3
(数组的长度),而 $b = (1, 2, 7)
将导致 $b
是 7
,因为逗号运算符只返回列表中的最后一个值,因为它是标量上下文。对吗? - temporary_user_name差异的简单演示。
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 表达式的一种形式(语法的一部分),而数组则是数据结构(内存位置)。
\(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]
操作。
数组 Vs 列表
列表是一种不同于数组的数据结构。
最大的区别在于直接访问 Vs 顺序访问的理念。数组允许直接和顺序访问,而列表只允许顺序访问。这是因为这些数据结构在内存中的存储方式不同。
此外,列表的结构不支持像数组那样的数字索引。元素也不需要像数组那样在内存中相邻地分配。
数组
数组是一个有序的项集合,其中每个项都有一个索引。
但主要区别在于:
数组有一个类似于元素数量
的标量上下文值
。
列表有一个类似于列表中的最后一个元素
的标量上下文值
。
所以,你需要了解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
#!math {2, 3, 2}
不是一个集合。 - darch