7

在 perl 中,括号用于覆盖优先级(如在大多数编程语言中)以及用于创建列表。如何判断一对特定的括号是否将被视为分组构造或单元素列表?

例如,我很确定这是一个标量而不是单元素列表:(1 + 1)
但是更复杂的表达式呢?有没有简单的方法可以分辨?

4

2 回答 2

17

三个关键原则在这里很有用:

语境为王。您的示例的评估(1 + 1)取决于上下文。

$x = (1 + 1); # Scalar context. $x will equal 2. Parentheses do nothing here.
@y = (1 + 1); # List context. @y will contain one element: (2).
              # Parens do nothing (see below), aside from following 
              # syntax conventions.

在标量上下文中,没有 list 之类的东西。要查看这一点,请尝试将看似列表的内容分配给标量变量。考虑这一点的方法是关注逗号运算符的行为:在标量上下文中,它评估其左侧参数,丢弃该值,然后评估其右侧参数,并返回该值。在列表上下文中,逗号运算符将两个参数都插入到列表中。

@arr  = (12, 34, 56); # Right side returns a list.

$x    = (12, 34, 56); # Right side returns 56. Also, we get warnings
                      # about 12 and 34 being used in void context.

$x = (@arr, 7);       # Right side returns 7. And we get a warning
                      # about using an array in a void context.

括号不创建列表。逗号运算符创建列表(假设我们在列表上下文中)。在 Perl 代码中键入列表时,需要括号是出于优先考虑的原因——而不是出于创建列表的原因。几个例子:

  • 括号没有作用:我们在标量上下文中评估一个数组,所以右边返回数组大小。

    $x = (@arr);
    
  • 创建包含一个元素的列表不需要括号。

    @arr = 33;         # Works fine, with @arr equal to (33).
    
  • 但是出于优先考虑的原因,多个项目需要括号。

    @arr = 12, 34, 56; # @arr equals (12). And we get warnings about using
                       # 34 and 56 in void context.
    
于 2010-05-22T03:37:10.963 回答
8
  1. 语境。
  2. 括号没有您认为它们在创建列表中的作用。

例子:

$x = 1 + 1;   # $x is 2.
$x = (1 + 1); # $x is 2.
@x = 1 + 1;   # @x is (2).
@x = (1 + 1); # @x is (2).

$x = (1 + 1, 1 + 2); # $x is 3.
@x = (1 + 1, 1 + 2); # @x is (2, 3).

粗略地说,在列表上下文中,逗号操作符分隔列表中的项目;在标量上下文中,逗号运算符是 C 的“串行逗号”,它计算其左侧和右侧,并返回右侧的值。在标量上下文中,括号组合表达式以覆盖操作顺序,而在列表上下文中,括号确实......完全相同。它们与分配给数组相关的原因是:

# Comma has precedence below assignment. 
# @a is assigned (1), 2 and 3 are discarded.
@a = 1, 2, 3; 

# @a is (1, 2, 3).
@a = (1, 2, 3);

至于您的问题“它是标量列表还是单元素列表”,由于上下文的原因,单独提出表达式并不是一个有意义的问题。在列表上下文中,一切都是列表;在标量上下文中,什么都不是。

推荐阅读:perlopperldataPerl 编程

于 2010-05-22T03:43:29.700 回答