【问题标题】:Why is Perl not doing the math here?为什么 Perl 不在这里做数学计算?
【发布时间】:2011-11-20 04:58:11
【问题描述】:

我有一个哈希引用数组:

my @price = (
    {
        id    => '1',
        label => 5.00
    },
    {
        id    => '2',
        label => 7.50
    },
);

我还有 2 个变量整数,$diff 和 $last。当我尝试遍历数组以将“标签”乘以 $diff/$last:

foreach (@price) {
    print "(($diff/$last)*$_->{label})\t";
}

我得到以下输出:

((12/30)*5.00)
((12/30)*7.50)

我假设它没有相乘,因为我有两个整数和一个哈希引用。如果这是正确的,我怎样才能使哈希引用成为整数?如何强制 Perl 实际进行数学运算并打印结果?

【问题讨论】:

  • 要吸取的教训:插值不是评估。

标签: arrays perl hash


【解决方案1】:

它没有相乘,因为所有这些都在双引号内。你需要做的:

print( (($diff/$last)*$_->{label}) . "\t" );

您在 perl 中的操作方式只是简单地插入变量并打印它们的值,因为它们包含在引号内。 * 被简单地视为要打印的字符。以上进行了数学运算,然后. 导致与"\t" 的连接(将结果转换为字符串)。

$a = 5;
$b = 6;
print "$a + $b\n";
print $a + $b . "\n";

输出:

5 + 6
11

【讨论】:

  • 您的代码不太好用。该标签从未打印过。将print(...) . "\t" 更改为print((...) . "\t")
  • 不要使用 $a$b 作为 var 名称。您会注意到缺少my 变量会转义strictwarnings,因为$a$b 应该在sort 块内使用
【解决方案2】:

你试过了吗:

foreach (@price) {
  $res = ($diff/$last)*$_->{label};
  print "$res\t";
}

即,在引号之外计算它,这样它就不会被解释为字符串。

【讨论】:

    【解决方案3】:

    我不建议评估像这种 inside 插值字符串这样的复杂表达式,但您可以通过两种方式进行。在我向你展示之前,让我告诉你插值是如何工作的。它主要是为了让您可以轻松地将 variables 与文字串起来。

    (( $diff / $last ) * $_->{label} )
    

    不是变量,它是一个表达式。然而,哈希索引$_->{label} 也是一个表达式,虽然是一个更简单的表达式,主要涉及索引 一个变量以查找其中存储的值。不同之处在于整个事情是几个操作,而不是试图显示已经存储的数据。

    但是,由于插值逻辑必须解析有时很复杂的表达式,因此您几乎可以插值任何表达式——如果它被“表述”为索引或取消引用。

    你可以做表达式解引用:

    print "${\(($diff/$last)*$_->{label})}\t";
    

    在这里,您 1) 解析表达式并 2) 引用它在内存中的位置,然后 3) 取消引用该部分内存。所以这就像取消引用,只是通过计算。

    还有文字数组插值:

    print "@{[ \(($diff/$last)*$_->{label}) ]}\t";
    

    在这里,您创建一个字面量数组,其中一个成员的值为表达式,并且您尊重它以让数组插值接管。

    同样,作为代码库的一部分,这些代码库必须存在数年之久。然而,它们是 Perl 的表达能力所允许的廉价而肮脏的技巧。

    【讨论】:

      【解决方案4】:

      出于同样的原因,它不会做数学运算

      print "Now at 1/2 price, buy 5!\n";
      

      不输出

      现在 0.5 的价格,买 120

      (如果只有 perl 会使用 '!' 来表示 '阶乘' :-)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-01-28
        • 2012-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多