【发布时间】:2010-11-24 08:48:14
【问题描述】:
我想对@a = @b || @c 赋值执行一些复杂的变体,如果@b 非空(因此在布尔意义上为真),则使用@c 否则。文档明确告诉我我不能。 (事实也是如此!)
“||”、“//”和“&&”运算符返回最后评估的值 (与 C 的 "||" 和 "&&" 不同,它们返回 0 或 1)。
[...]
特别是,这意味着您不应该使用它来选择 分配的两个聚合之间:
@a = @b || @c; # this is wrong @a = scalar(@b) || @c; # really meant this @a = @b ? @b : @c; # this works fine, though
不幸的是,它并没有真正告诉我原因。
我预计会发生这样的事情:
-
@a =是一个数组赋值,在右侧引入列表上下文。 -
@b || @c是右侧,将在列表上下文中进行评估。 -
||是 C 风格的短路逻辑或。它从左到右评估(如果需要)并传播上下文。 -
@b在列表上下文中进行评估。如果为真(即,非空),则返回。 - 如果不是,
@c也会在列表上下文中进行评估并返回。
显然,我的倒数第二句话是错误的。为什么?而且,更重要的是,文档或来源的哪一部分解释了这种行为?
PS:在问题的范围之外,我不建议使用三元运算符的原因是我的 @b 实际上是一个临时的(函数调用结果)。
【问题讨论】:
-
“真的是这个意思”这行告诉你原因。
-
对我来说,这更像是什么而不是为什么。但我有偏见。
-
我宁愿认为评论“真的意味着这个”应该改为“真的意味着这个”。就这样,我期待 scalar() 更改将@a 设置为等于@b - 即成为作者真正想要使用的东西 - 显然情况并非如此。相反,第一行实际上意味着第二行。他们都得到相同的结果,这不是我们想要的答案。