切片(Slice)

Slice指的是从列表、数组、hash中根据指定的索引取一个或多个元素。

在列表上下文,切片返回一个包含所取得元素值的列表。在标量上下文,返回所取得的最后一个元素值。

例如,列表切片:

# 取列表中index=0、1和3的元素,
# 列表上下文中返回所取得元素的列表,赋值给数组
my @arr = (11, 22, 33, 44)[0,1,3];  # 11 22 44

数组切片:

my @arr = (11, 22, 33, 44, 55);
my @arr = @arr[1,2,3]  # 22 33 44

切片时中括号里提供的索引是一个列表,索引可以重复,可以用负数索引,可以用范围表达式(如1..3表示1 2 3)。但要注意,索引越界将取得undef值。

(11, 22, 33, 44)[0,1,1,-1];  # 11 22 22 44
(11, 22, 33, 44)[0..2];      # 11 22 33
(11, 22, 33, 44)[0, 2..3];   # 11 33 44
(11, 22, 33, 44)[0, 1, 30];  # 11 22 undef

有时候需要从列表或数组中随机取一个或多个元素,可以将rand()的结果作为切片的索引值:

my @arr = ('a'..'z', 'A'..'Z');
say "@arr[rand 52, rand 52]";  # 取两个随机元素

有时候需要取得数组的最后几个元素值(例如perl一行式命令中经常需要取最后几个字段的值),这时可利用数组的最大索引来转换计算:

my @arr = (11,22,33,44,55,66);

# 取最后一个元素
my @arr[$#arr];   # 或:@arr[-1]

# 取最后四个元素
my @arr[$#arr-3..$#arr];

数组切片和列表切片在使用上有一些区别:

  • 数组切片可以内插到双引号中,而列表切片不能内插到双引号
  • 数组切片可以作为左值,列表切片则不行

例如:

# 内插数组切片
my @arr = (11,22,33,44);
say "@arr[0,1,1]";

# 数组切片作为左值
my @langs = qw(perl python shell php);
@langs[1,2]=qw(ruby bash); # 将python改为ruby,shell改为bash
say "@langs";   # perl ruby bash php