【问题标题】:Perl Hash Slice, Replication x Operator, and sub paramsPerl 哈希切片、复制 x 运算符和子参数
【发布时间】:2010-06-03 20:54:55
【问题描述】:

好的,我了解 perl 哈希切片和 Perl 中的 the "x" operator,但是有人可以解释一下 here 中的以下代码示例(稍微简化)吗?

sub test{
    my %hash;
    @hash{@_} = (undef) x @_;
}

调用子示例:

test('one', 'two', 'three');

这句话让我很震惊:

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

它正在创建一个哈希,其中键是 sub 的参数并初始化为 undef,所以:

%哈希:

'one' => undef, '二' => undef, '三' => undef

x 运算符的右值应该是一个数字; @_ 是如何被解释为子参数数组的长度的?我希望您至少必须这样做:

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

【问题讨论】:

  • length() 返回字符串的长度,而不是数组。请参阅 perldoc perlfunc。
  • 更新示例以使用标量而不是长度 - 谢谢
  • FWIW,@hash{@_} = () 是实现相同哈希初始化的更简单、更有效的方法。
  • 我希望 undef @hash{@_} 也能工作,但似乎 undef 并没有分布在表达式中的所有左值中。 :(
  • @Ether,真的吗?正如我所料,在 5.10 下,undef @h{@keys} 会创建所有以前非 existsing 的密钥。

标签: perl hash slice replicate


【解决方案1】:

要弄清楚这段代码,你需要了解三件事:

重复运算符。x 运算符是repetition operator。在列表上下文中,如果运算符的左侧参数括在括号中,它将重复列表中的项目:

my @x = ('foo') x 3;  # ('foo', 'foo', 'foo')

标量上下文中的数组。 在标量上下文中使用数组时,它会返回其大小。 x 运算符将标量上下文强加于其右侧参数。

my @y = (7,8,9);
my $n = 10 * @y; # $n is 30

散列切片。hash slice 语法提供了一种同时访问多个散列项的方法。哈希切片可以检索哈希值,也可以分配给它。在本例中,我们正在分配一个哈希切片。

# 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 @_;

【讨论】:

  • 解释得很清楚。似乎您只需要知道重复 x 运算符将在标量上下文中内部使用您的右手 arg,即使它是一个数组。
  • 在列表上下文中 AND 左操作数用括号括起来(或者是一个 qw)时,它是一个列表重复。而且,不是或。
【解决方案2】:

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

如果在标量上下文中计算数组,它会返回数组的长度。 (请注意,列表不是这样,它返回最后一个值,如 C 逗号运算符,也不是内置函数,它们返回他们想要返回的任何内容。)

虽然我目前无法找到有关它的更多信息,但复制运算符似乎在标量上下文中评估其第二个参数,从而导致数组评估为其长度。

【讨论】:

  • x 运算符的 RHS 必须是数字(或看起来像数字的东西),因此它确实在标量上下文中评估它。
  • 它只是让我感到困惑,因为您通常将 $ sigil 用于标量,将 @sigil 用于数组,但此示例仅使用 @ sigil ...所以它只是隐含您在标量之后?使用标准数组@arr,您将通过标量上下文$arr 获得长度。也许问题是为什么要这样做——因为 $_ 是一个特殊的变量?
  • 不,这与它无关 - 尝试任何其他数组,它会工作。正如friedo 评论的那样,“标量化”,即标量上下文,是由复制运算符引起的。如果你想明确,可以使用scalar @arrayscalar(@array),这样你就不会忘记你在看一个标量。
  • @user210757 $foo@foo 是一个完全不相关的变量
  • hobbs - 我的错误,我在想 "@foo" 与 "scalar @foo" - foo 的标量上下文。
猜你喜欢
  • 1970-01-01
  • 2013-08-10
  • 1970-01-01
  • 1970-01-01
  • 2015-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-29
相关资源
最近更新 更多