为啥在 Perl 中 'print (52-80)*42' 与 'print 42*(52-80)' 不同?
Posted
技术标签:
【中文标题】为啥在 Perl 中 \'print (52-80)*42\' 与 \'print 42*(52-80)\' 不同?【英文标题】:Why is 'print (52-80)*42' different than 'print 42*(52-80)' in Perl?为什么在 Perl 中 'print (52-80)*42' 与 'print 42*(52-80)' 不同? 【发布时间】:2011-04-17 21:48:05 【问题描述】:Perl:: 什么是:
1. (52-80)*42
2. 42*(52-80)
回答:
1. -28
2. -1176
为什么?
请尽情地解释/证明这一点!
#!/usr/bin/perl
use strict;
print 42*(52-80) , "\n";
print ((52-80)*42) , "\n";
print (52-80)*42 , "\n";
print "\n";
my $i=(52-80)*42;
print $i, "\n";
输出:
> -1176
> -1176-28
> -1176
【问题讨论】:
鉴于您的输出中没有足够的换行符,我认为这不是您实际运行的代码,是吗? @Ben 试试看。它确实产生了该输出。提示:这不是数学或优先级问题,而是括号解析问题... 标题和问题当然是错误的。-28
的结果取决于更大的代码 sn-p。
你错过了关键的use warnings;
我们在Learning Perl 中专门讨论了这个问题。人们可能会认为阅读这本书是在浪费时间,但我想知道人们不阅读它浪费了多少时间。
【参考方案1】:
如果您添加use warnings;
,您将获得:
print (...) interpreted as function at ./test.pl line 5.
Useless use of a constant in void context at ./test.pl line 5
【讨论】:
【参考方案2】:感谢 Perl 古怪的解析规则(哦 Perl,你疯了!),这些语句:
print ((52-80)*42) , "\n";
print (52-80)*42 , "\n";
被解释为好像它们是写的:
(print ((52-80)*42)), "\n";
(print (52-80))*42, "\n";
这就是为什么您最终会在一行中看到-1176-28
,并且缺少预期的空白行。 Perl 看到 (print-expr), "\n";
并简单地丢弃换行符而不是打印它。
【讨论】:
任何其他选择在其他情况下都一样古怪。除非您真正的抱怨是所有参数都应该始终使用括号?【参考方案3】:Alex Howansky 暗示的警告意味着
print (52-80)*42 , "\n"
被解析为
(print(52-80)) * 42, "\n"
也就是说,一个列表包含 (1) 函数 print(-28)
的结果的 42 倍,以及 (2) 包含换行符的字符串。 (1) 的副作用是将值 -28
(不带换行符)打印到标准输出。
如果您需要打印以括号开头的表达式,解决方法是在其前面加上+
:
print +(52-80)*42, "\n" # ==> -1176
【讨论】:
或者只是打印到一个文件句柄,就像任何 sane.... 等一下,我正要在同一个句子中使用 sane 和 Perl。我在想什么? 或者,如果您不确定如何解释它们,就不要使用隐式括号。记住,伙计们,速记不是强制性的。 这不是一个列表(如 void context 警告所示)。 这是一个列表(你可以通过逗号来判断)。无效上下文警告是关于列表第二个元素中无用的"\n"
。以上是关于为啥在 Perl 中 'print (52-80)*42' 与 'print 42*(52-80)' 不同?的主要内容,如果未能解决你的问题,请参考以下文章
xampp中的perl文件夹有啥用,为啥它包含在xampp中? [关闭]
为啥 PowerShell(使用 Perl)在简单的打印语句中删除双引号?