为什么我不能分配@b || Perl 中的@c 到@a?
我想执行 @a = @b || 的一些复杂变体@c
赋值,目的是如果非空则采用 @b
(因此在布尔意义上为 true),否则采用 @c
。文档明确告诉我不能。 (事实也是如此!)
“||”、“//”和“&&”运算符返回最后计算的值 (与 C 的“||”和“&&”不同,它们返回 0 或 1)。
[...]
特别是,这意味着您不应该使用它来选择 两个聚合之间的分配:
<前><代码>@a = @b || @c; # 这是错误的 @a = 标量(@b) || @c; # 真正的意思是这个 @a=@b? @b:@c; # 不过这工作得很好
不幸的是,它并没有真正告诉我原因。
我期望发生的是这样的:
@a =
是一个数组赋值,在右侧引入列表上下文。- <代码>@b || @c 是右侧,将在列表上下文中进行评估。
||
是 C 风格的短路逻辑或。它从左到右评估(如果需要)并传播上下文。@b
在列表上下文中计算。如果为 true(ie,非空),则返回。- 如果不是,
@c
也会在列表上下文中求值并返回。
显然,我倒数第二个说法是错误的。为什么?而且,更重要的是,文档或来源的哪一部分解释了这种行为?
PS:超出了问题的范围,我不使用文档建议使用三元运算符的原因是我的 @b
实际上是临时的(函数调用结果)。
I'd like to perform some convoluted variation of the @a = @b || @c
assignment, with the intent of taking @b
if non-empty (hence true in a boolean sense), @c
otherwise. The documentation explicitely tells me I can't. (And it's right about the fact, too!)
The "||", "//" and "&&" operators return the last value evaluated
(unlike C's "||" and "&&", which return 0 or 1).[...]
In particular, this means that you shouldn't use this for selecting
between two aggregates for assignment:@a = @b || @c; # this is wrong @a = scalar(@b) || @c; # really meant this @a = @b ? @b : @c; # this works fine, though
Unfortunately, it doesn't really tell me why.
What I expected would happen was this:
@a =
is an array assignment, inducing list context on the right hand side.@b || @c
is the right hand side, to be evaluated in list context.||
is C-style short-circuit logical or. It evaluates left to right (if needed) and propagates context.@b
is evaluated in list context. If true (i.e., non-empty), it is returned.- if not,
@c
is evaluated in list context as well, and returned.
Obviously, my penultimate statement is wrong. Why? And, more importantly, which part of the documentation or sources account for this behavior?
PS: out of the question's scope, the reason I refrain from the documentation's suggestion of using the ternary operator is that my @b
is actually a temporary (a function call result).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
逻辑或运算符 ( "
||
" ) 在标量上下文中计算其左侧参数。它这样做的原因是为了弄清楚这个论点是否正确。布尔上下文是标量上下文的特例,强制其进入标量上下文。
来自
perldoc perlop
"C-style-Logical-Or"来自
perldoc perldata
"标量值":The logical-or operator ( "
||
" ) evaluates its left hand argument in scalar context.The reason it does this is to figure out if the argument is true. Boolean context, being a special case of scalar context, forces it into scalar context.
From
perldoc perlop
"C-style-Logical-Or"From
perldoc perldata
"Scalar values":在 perlop 中,仅在您引用的部分之前有几段:
这并没有明确说明列表上下文不会传播到左操作数,但 perlop 的顶部声明:
因此我们可以假设传播到右操作数的列表上下文是这
该规则的例外情况,并且缺乏有关上下文的任何声明
左操作数意味着适用一般规则。
In perlop, just a few paragraphs before the section you quote:
This doesn't explicitly state that list context does not propagate to the left operand, but the top of perlop states:
so we can assume that list context propagating to the right operand is the
exception to the rule, and the lack of any statement about the context of
the left operand implies the general rule applies.
正是因为 ||在标量上下文中计算左侧,就像 ?: 的测试参数一样。
如果不能使用三元,请使用函数:
It's because || evaluates the left side in scalar context, as does the test argument of ?: .
If you can't use the ternary, use a function:
如果您不能直接使用条件运算符,您可以轻松地使用稍微不太简洁的:
根据上面的答案,您的代码不起作用,因为
||
左侧的逻辑上下文在标量上下文中求值,因此@b
实际上变成了scalar(@b)
,这就是分配给@a
的内容。If you can't use the conditional operator directly, you can easily use the slightly-less-terse:
As per above answer, your code does not work since the logical context that the left side of
||
is evaluated in is a scalar context and thus@b
actually becomesscalar(@b)
and that is what gets assigned to@a
.