gpt4 book ai didi

perl - 山羊运算符(operator)为什么工作?

转载 作者:行者123 更新时间:2023-12-03 08:14:06 24 4
gpt4 key购买 nike

数组和列表之间以及列表和标量上下文之间的区别去年在 Perl 社区中进行了很多讨论(实际上每年都如此)。我已经阅读了来自 chromatic 的文章和 friedo ,以及 this推荐修士节点。我现在正在尝试了解 goatse 运算符,记录在 perlsecret 中.

这是我用来研究它的一些代码:

# right side gets scalar context, so commas return rightmost item
$string = qw(stuff junk things);
say $string; # things

# right side gets list context, so middle is list assigned in scalar context
$string = () = qw(stuff junk things);
say $string; # 3

# right side gets list context, so creates a list, assigns an item to $string2, and
# evaluates list in scalar context to assign to $string
$string = ($string2) = qw(stuff junk things);
say $string; # 3
say $string2; # stuff

我想我已经足够了解所有列表和标量上下文的工作原理。标量上下文中的逗号运算符返回其右侧,因此第一个示例简单地将逗号表达式中的最后一项(不带任何逗号)分配给 $string .在其他示例中,将逗号表达式分配给列表会将其置于列表上下文中,因此创建了一个列表,并在标量上下文中评估的列表返回其大小。

有两部分我不明白。

首先,列表应该是不可变的。弗里多反复强调了这一点。我猜这个任务来自 =从列表到列表将分配从一个列表中的项目分配到另一个列表中的项目,这就是为什么在第二个示例中 $string2获取 'stuff' ,以及为什么我们可以打开包装 @_通过列表分配。但是,我不明白如何分配给 () ,一个空列表,可能会起作用。以我目前的理解,由于列表是不可变的,列表的大小将保持为 0,然后将大小分配给 $stuff在示例 2 和示例 3 中,它的值为 0。列表实际上不是不可变的吗?

其次,我多次阅读到列表实际上并不存在于标量上下文中。但是山羊运算符的解释是它是标量上下文中的列表赋值。这不是标量上下文中不存在列表的说法的反例吗?还是这里发生了其他事情?

更新:在理解了答案之后,我认为一对额外的括号有助于概念化它的工作原理:
$string = ( () = qw(stuff junk things) );

在括号内, =是对“聚合”的赋值,列表赋值运算符也是如此(它与标量赋值运算符不同,不应与“列表上下文”混淆;列表和标量赋值可以在列表或标量上下文中发生)。 ()不会以任何方式改变。 = Perl中有返回值,列表赋值的结果赋值给 $string通过左侧 = .分配给 $string为 RHS 提供标量上下文(括号中的所有内容),在标量上下文中,列表赋值运算符的返回值是 RHS 中的项目数。

您可以将 RHS 列表分配放入列表上下文中:
($string) = ( () = qw(stuff junk things) );

根据 perlop列表上下文中的列表赋值返回已赋值左值的列表,这里是空的,因为在 () 中没有要赋值的内容。 .所以这里 $string 将是 undef .

最佳答案

请记住,在 Perl 中,赋值是一个表达式,您应该考虑表达式的值(赋值运算符的值),而不是“列表的值”。

表达式的值 qw(a b)('a', 'b')在列表上下文中和 'b'在标量上下文中,但表达式的值 (() = qw(a b))()在列表上下文中和 2在标量上下文中。 (@a = qw(a b)) 的值遵循相同的模式。这是因为 pp_aassign ,列表赋值运算符,选择在标量上下文中返回一个计数:

else if (gimme == G_SCALAR) {
dTARGET;
SP = firstrelem;
SETi(lastrelem - firstrelem + 1);
}

(pp_hot.c 第 1257 行;行号可能会发生变化,但接近 PP(pp_aassign) 的结尾。)

然后,除了赋值运算符的值之外,还有赋值运算符的副作用。列表赋值的副作用是将值从其右侧复制到其左侧。如果右侧先用完值,则左侧剩余的元素得到 undef ;如果左侧首先用完值,则不会复制右侧的剩余元素。当 LHS 为 () 时,列表分配根本不会在任何地方复制任何内容。但是赋值本身的值仍然是 RHS 中元素的数量,如代码片段所示。

关于perl - 山羊运算符(operator)为什么工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21037846/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com