8

我有一个小问题。我正在阅读一些代码,因为我的学校没有教我任何有关 perl 编程的有用知识,所以我在这里问你们。我看到这一行在一些 perl 程序中被大量使用:

$variable = &something();

我不知道这个&符号在这里是什么意思,因为我从不在 perl 中说出来。这something是一个子程序(我猜)。它通常说一个名字,有时它也有像函数一样的参数。有人可以告诉我&这里代表什么以及something一直是什么。

该变量接受某种返回值,然后用于检查某些条件,这让我认为它是一个子程序。但还是为什么&

谢谢

4

2 回答 2

29

几乎每次你在and&之外看到,它都是一个错误。\&fooEXRP && EXPR


  • &foo(...)foo(...)与exceptfoo的原型相同,将被忽略。

    sub foo(&@) { ... }      # Cause foo to takes a BLOCK as its first arg
    
    foo { ... } ...;
    &foo(sub { ... }, ...);  # Same thing.
    

    只有子程序(不是运算符)会被&foo(...).

    sub print { ... }
    print(...);         # Calls the print builtin
    &print(...);        # Calls the print sub.
    

    在整个编程生涯中,您可能永远不需要使用此功能。如果您看到它被使用,那么肯定有人&在不应该使用的时候使用它。

  • &foo类似于&foo(@_)。不同之处在于更改@_infoo会影响当前 sub 的@_.

    在整个编程生涯中,您可能永远不需要使用此功能。如果您看到它被使用,那肯定是有人&在不应该使用的时候使用它,或者是愚蠢的优化尝试。但是,以下内容非常优雅:

    sub log_info  { unshift @_, 'info';  &log }
    sub log_warn  { unshift @_, 'warn';  &log }
    sub log_error { unshift @_, 'error'; &log }
    
  • goto &foo类似于&foo,除了当前子例程首先从调用堆栈中删除。例如,这将导致它不会出现在堆栈跟踪中。

    在整个编程生涯中,您可能永远不需要使用此功能。如果您看到它被使用,那肯定是一种愚蠢的优化尝试。

    sub log_info  { unshift @_, 'info';  goto &log; } # These are slower than
    sub log_warn  { unshift @_, 'warn';  goto &log; } # not using goto, but maybe
    sub log_error { unshift @_, 'error'; goto &log; } # maybe log uses caller()?
    
  • $&包含最后一个正则表达式匹配匹配的内容。在 5.20 之前,使用它会导致整个解释器中的每个正则表达式变慢(如果它们没有捕获),所以不要使用它。

    print $&        if /fo+/;     # Bad before 5.20
    print $MATCH    if /fo+/;     # Bad (Same thing. Requires "use English;")
    print ${^MATCH} if /fo+/p;    # Ok (Requires Perl 5.10)
    print $1        if /(fo+)/;   # Ok
    
  • defined &foo是检查子例程是否存在的一种完全合法的方法,但它不是您可能永远需要的东西。也exists &foo有类似的,但没有那么有用。

  • EXPR & EXPR是按位与运算符。这在处理将多条信息存储在一个单词中的低级系统时使用。

    system($cmd);
    die "Can't execute command: $!\n"       if $? == -1;
    die "Child kill by ".($? & 0x7F)."\n"   if $? & 0x7F;
    die "Child exited with ".($? >> 8)."\n" if $? >> 8;
    
  • &{ EXPR }()(and &$ref()) 是通过引用进行的子例程调用。$ref->()尽管我更喜欢这种语法,但这是一件完全可以接受且有些常见的事情。下一项中的示例。

  • \&foo引用 subroutine foo。这是一个完全可以接受且有些常见的事情。

    my %dispatch = (
       foo => \&foo,
       bar => \&bar,
    );
    
    my $handler = $dispatch{$cmd} or die;
    $handler->();
    # Same:  &{ $handler }();
    # Same:  &$handler();
    
  • EXPR && EXPR是布尔 AND 运算符。我相信你对这个极其常见的运算符很熟悉。

    if (0 <= $x && $x <= 100) { ... }
    
于 2013-06-18T16:16:18.627 回答
14

在旧版本的 perl&中用于调用子例程。现在这不是必需的,\&主要用于采取referenceto 子程序,

my $sub_ref = \&subroutine;

或忽略函数原型(http://perldoc.perl.org/perlsub.html#Prototypes

除了引用子程序&bitwise and操作符,

http://perldoc.perl.org/perlop.html#Bitwise-And

于 2013-06-18T16:11:11.967 回答