使用 Range 变量作为下标获取位置切片
Getting a positional slice using a Range variable as a subscript
my @numbers = <4 8 15 16 23 42>;
这个有效:
.say for @numbers[0..2]
# 4
# 8
# 15
但这不是:
my $range = 0..2;
.say for @numbers[$range];
# 16
下标似乎将 $range
解释为范围 (3) 中的元素数。什么给了?
按预期工作。将范围对象扁平化为列表 @numbers[|$range]
or use binding on Range objects to hand them around. https://docs.perl6.org 将很快更新。
On Fri Jul 22 15:34:02 2016, gfldex wrote:
> my @numbers = <4 8 15 16 23 42>; my $range = 0..2; .say for
> @numbers[$range];
> # OUTPUT«16»
> # expected:
> # OUTPUT«4815»
>
This is correct, and part of the "Scalar container implies item" rule.
Changing it would break things like the second evaluation here:
> my @x = 1..10; my @y := 1..3; @x[@y]
(2 3 4)
> @x[item @y]
4
Noting that since a range can bind to @y in a signature, then Range being a
special case would make an expression like @x[$(@arr-param)]
unpredictable in its semantics.
> # also binding to $range provides the expected result
> my @numbers = <4 8 15 16 23 42>; my $range := 0..2; .say for
> @numbers[$range];
> # OUTPUT«4815»
> y
This is also expected, since with binding there is no Scalar container to
enforce treatment as an item.
So, all here is working as designed.
绑定到 Scalar container 的符号会产生一件事
获得所需内容的选项包括:
- 前缀为
@
以获得单个事物的复数视图:numbers[@$range]
;或者
- 以不同方式声明范围变量,使其直接工作
对于后一种选择,请考虑以下因素:
# Bind the symbol `numbers` to the value 1..10:
my \numbers = [0,1,2,3,4,5,6,7,8,9,10];
# Bind the symbol `rangeA` to the value 1..10:
my \rangeA := 1..10;
# Bind the symbol `rangeB` to the value 1..10:
my \rangeB = 1..10;
# Bind the symbol `$rangeC` to the value 1..10:
my $rangeC := 1..10;
# Bind the symbol `$rangeD` to a Scalar container
# and then store the value 1..10 in it:`
my $rangeD = 1..10;
# Bind the symbol `@rangeE` to the value 1..10:
my @rangeE := 1..10;
# Bind the symbol `@rangeF` to an Array container and then
# store 1 thru 10 in the Scalar containers 1 thru 10 inside the Array
my @rangeF = 1..10;
say numbers[rangeA]; # (1 2 3 4 5 6 7 8 9 10)
say numbers[rangeB]; # (1 2 3 4 5 6 7 8 9 10)
say numbers[$rangeC]; # (1 2 3 4 5 6 7 8 9 10)
say numbers[$rangeD]; # 10
say numbers[@rangeE]; # (1 2 3 4 5 6 7 8 9 10)
say numbers[@rangeF]; # (1 2 3 4 5 6 7 8 9 10)
绑定到标量容器 ($rangeD
) 的符号始终产生单个值。在 [...]
下标中,单个值必须是数字。一个范围被视为单个数字,产生该范围的长度。
my @numbers = <4 8 15 16 23 42>;
这个有效:
.say for @numbers[0..2]
# 4
# 8
# 15
但这不是:
my $range = 0..2;
.say for @numbers[$range];
# 16
下标似乎将 $range
解释为范围 (3) 中的元素数。什么给了?
按预期工作。将范围对象扁平化为列表 @numbers[|$range]
or use binding on Range objects to hand them around. https://docs.perl6.org 将很快更新。
On Fri Jul 22 15:34:02 2016, gfldex wrote:
> my @numbers = <4 8 15 16 23 42>; my $range = 0..2; .say for
> @numbers[$range];
> # OUTPUT«16»
> # expected:
> # OUTPUT«4815»
>
This is correct, and part of the "Scalar container implies item" rule.
Changing it would break things like the second evaluation here:
> my @x = 1..10; my @y := 1..3; @x[@y]
(2 3 4)
> @x[item @y]
4
Noting that since a range can bind to @y in a signature, then Range being a
special case would make an expression like @x[$(@arr-param)]
unpredictable in its semantics.
> # also binding to $range provides the expected result
> my @numbers = <4 8 15 16 23 42>; my $range := 0..2; .say for
> @numbers[$range];
> # OUTPUT«4815»
> y
This is also expected, since with binding there is no Scalar container to
enforce treatment as an item.
So, all here is working as designed.
绑定到 Scalar container 的符号会产生一件事
获得所需内容的选项包括:
- 前缀为
@
以获得单个事物的复数视图:numbers[@$range]
;或者 - 以不同方式声明范围变量,使其直接工作
对于后一种选择,请考虑以下因素:
# Bind the symbol `numbers` to the value 1..10:
my \numbers = [0,1,2,3,4,5,6,7,8,9,10];
# Bind the symbol `rangeA` to the value 1..10:
my \rangeA := 1..10;
# Bind the symbol `rangeB` to the value 1..10:
my \rangeB = 1..10;
# Bind the symbol `$rangeC` to the value 1..10:
my $rangeC := 1..10;
# Bind the symbol `$rangeD` to a Scalar container
# and then store the value 1..10 in it:`
my $rangeD = 1..10;
# Bind the symbol `@rangeE` to the value 1..10:
my @rangeE := 1..10;
# Bind the symbol `@rangeF` to an Array container and then
# store 1 thru 10 in the Scalar containers 1 thru 10 inside the Array
my @rangeF = 1..10;
say numbers[rangeA]; # (1 2 3 4 5 6 7 8 9 10)
say numbers[rangeB]; # (1 2 3 4 5 6 7 8 9 10)
say numbers[$rangeC]; # (1 2 3 4 5 6 7 8 9 10)
say numbers[$rangeD]; # 10
say numbers[@rangeE]; # (1 2 3 4 5 6 7 8 9 10)
say numbers[@rangeF]; # (1 2 3 4 5 6 7 8 9 10)
绑定到标量容器 ($rangeD
) 的符号始终产生单个值。在 [...]
下标中,单个值必须是数字。一个范围被视为单个数字,产生该范围的长度。