Perl哈希片、复制x运算符和子参数

Perl哈希片、复制x运算符和子参数,perl,hash,slice,replicate,Perl,Hash,Slice,Replicate,好的,我理解perl散列切片,并且使用perl,但是有人可以解释下面的代码示例吗(稍微简化) 调用sub的示例: test('one', 'two', 'three'); 这句话让我联想到: @hash{@_} = (undef) x @_; 它正在创建一个散列,其中键是sub的参数,并初始化为undef,因此: %散列: “一”=>未定义, “两个”=>未定义, “三个”=>未定义 x运算符的右值应该是一个数字;如何将@u解释为sub参数数组的长度?我想你至少应该这样做: @hash{@_

好的,我理解perl散列切片,并且使用perl,但是有人可以解释下面的代码示例吗(稍微简化)

调用sub的示例:

test('one', 'two', 'three');
这句话让我联想到:

@hash{@_} = (undef) x @_;
它正在创建一个散列,其中键是sub的参数,并初始化为undef,因此:

%散列:

“一”=>未定义, “两个”=>未定义, “三个”=>未定义

x运算符的右值应该是一个数字;如何将@u解释为sub参数数组的长度?我想你至少应该这样做:

@hash{@_} = (undef) x scalar @_;

在标量上下文中,数组计算为其长度。从
perldoc perldata

如果在标量上下文中计算数组,它将返回数组的长度。(请注意,对于返回最后一个值的列表(如C逗号运算符)和返回任何想要返回的内容的内置函数,情况并非如此。)


虽然我目前找不到关于它的更多信息,但复制操作符似乎在标量上下文中计算其第二个参数,从而导致数组计算到其长度。

要理解此代码,您需要了解三件事:

重复运算符。
x
运算符是重复运算符。在列表上下文中,如果操作符的左参数用括号括起来,它将重复列表中的项目:

my @x = ('foo') x 3;  # ('foo', 'foo', 'foo')
标量上下文中的数组。当在标量上下文中使用数组时,它返回其大小。
x
运算符将标量上下文强加给其右侧参数

my @y = (7,8,9);
my $n = 10 * @y; # $n is 30
哈希切片。该语法提供了一种同时访问多个哈希项的方法。哈希片可以检索哈希值,也可以分配给。在本例中,我们将分配给一个哈希片

# Right side creates a list of repeated undef values -- the size of @_.
# We assign that list to a set of hash keys -- also provided by @_.
@hash{@_} = (undef) x @_;
做同样事情的不那么晦涩的方法:

@hash{@_} = ();
$hash{$_} = undef for @_;

length()返回字符串的长度,而不是数组的长度。请参阅perldoc perlfunc.updated示例以使用标量而不是长度-thanksFWIW,
@hash{@}=()
是实现相同哈希初始化的更简单、更有效的方法。我希望
unde@hash{@}
也能起作用,但似乎unde并没有分布在表达式中的所有左值上(@Ether,真的吗?在5.10下,
undef@h{@keys}
创建所有以前不存在的
键,正如我所期望的那样。
x
操作符的RHS必须是一个数字(或看起来像数字的东西)所以它确实是在标量上下文中计算的。这让我很困惑,因为你通常使用$sigil表示标量,@sigil表示数组,但这个示例只使用@sigil…所以它只是暗示你在标量后面?对于标准数组@arr,你可以通过标量上下文$arr获得长度。也许问题是为什么这样做-因为$是一个特殊变量?不,这与它无关-尝试任何其他数组,它都会工作。正如friedo所评论的,“标量化”,即标量上下文,是由复制运算符引起的。如果您想明确地说清楚,可以使用
scalar@array
scalar(@array)
这样你就不会忘记你看到的是一个标量。@user210757
$foo
是一个与
@foo
完全无关的变量。霍布斯-我错了,我想的是“@foo”和“scalar@foo”-foo的标量上下文。非常清楚的解释。似乎您只需要知道重复x运算符将在标量上下文中内部使用您的右手参数,即使它是数组。在列表上下文中,它是列表重复,左侧操作数括在括号中(或是qw)。和,而不是或。
@hash{@_} = ();
$hash{$_} = undef for @_;