【问题标题】:In Perl,is there a way to do simple arithmetic inside quotes?在 Perl 中,有没有办法在引号内进行简单的算术运算?
【发布时间】:2011-07-05 06:33:39
【问题描述】:
$i = 5;
print "{$i*10}";

有时我可能需要做上面的事情,但是 Perl 并没有按照我想要的方式解释它,我只能用另一个变量来做。有什么诀窍吗?

【问题讨论】:

    标签: perl


    【解决方案1】:
    $i = 5;
    print "${\($i*10)}";
    

    print "@{[$i*10]}";
    

    这些插入一个“变量”,它是一个代码块的解引用,其中包含适当类型的引用(第一个实例中的标量,第二个实例中的数组)。

    另一种方法是使用一个始终将键作为值返回的虚拟哈希:

    use strict;
    use warnings;
    
    {
        package Tie::Hash::Dummy;
        use Tie::Hash;
        use parent -norequire => 'Tie::StdHash';
        sub FETCH { $_[1] }
        tie our %Lookup, __PACKAGE__;
    }
    
    my $i = 5;
    print "$Tie::Hash::Dummy::Lookup{$i*10}";
    

    另一种方法是使用\N{} 字符名称查找接口,尽管这会在编译时绑定来自不同位置的变量(以及使用字符串 eval,可能存在安全问题):

    my $i;
    BEGIN { $i = 5 }
    BEGIN { $^H{'charnames'} = sub { eval $_[0] } }
    print "\N{$i*10}";
    

    (如果 charnames 处理程序返回一个在字符串化时执行 eval 的重载代理对象,这个可能会更好,但我没有时间尝试它。)

    另一种方法是使用重载::constant() 设置字符串常量处理程序。

    【讨论】:

    • \ 具有更高的优先级,因此它采用对 $i 的引用并将其乘以 10,然后将其结果用作符号引用。您需要引用整个表达式(然后使用 ${} 取消引用):"${\( EXPR )}"
    • 你确定\( EXPR ) 没有被解释为引用数组,而是因为它只有一个成员,所以计算结果与引用标量相同?
    • 是的,我确定。 perl 中的 () 从不创建内容列表或数组,它只会影响优先级。也就是说,\() 有点特殊,因为它返回对 () 中包含的元素的引用列表,但在您的情况下只有一个。
    • 从来没有? @arr = (1,2,3);,这个呢?我的疑问是 () 是在创建列表还是作为括号?
    • 括号唯一的作用是导致低优先级首先发生。没有它们,@arr = 1,2,3 将变为 (@arr = 1),2,3。 () 不创建列表。
    【解决方案2】:

    我建议你使用“printf”:

    printf("%s",$i*10);
    

    这样就可以了。

    【讨论】:

    • 有了所有其他选项,这个选项在 99.999% 的时间里都是正确的。
    【解决方案3】:
    $i = 5;
    print "${\($i*10)}";
    

    我不建议这样做!

    更新:它(或多或少)等同于:

    $i = 5;
    $j = ($i * 10);
    $k = \$j;
    print "${$k}";
    

    【讨论】:

    • Perl 将取消引用插入为${EXPR}@{EXPR},因此您所要做的就是编写一个表达式,返回对您想要的值的引用。
    【解决方案4】:

    你可以试试下面的,

    print "{". $i*10. "}";
    

    【讨论】:

    • 我想用引号括起来。
    【解决方案5】:

    您是否正在尝试访问哈希?

    如果没有,那么只需使用: print "{".($i*10)"}";

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-09
      • 2021-04-28
      • 1970-01-01
      • 2020-01-26
      • 2019-06-02
      • 2019-04-30
      • 1970-01-01
      • 2012-09-02
      相关资源
      最近更新 更多