perl中parens / bracket使用的规则(?)

时间:2013-04-22 17:57:18

标签: perl square-bracket curly-brackets

进行了一些搜索但找不到任何有用的内容。 我想知道是否有一个摘要表,供初学者了解使用parens / bracket的“规则”,特别是(),[],{}之间的差异。 不幸的是,根据我的经验,use strictuse warnings并没有告诉我是否使用了错误的数据。

例如,下面是合法代码(b / c来自ikegami)。

@{"genotype".($i)}
@{$genotype[$i]}
$genotype[$i] = [ split (/:/, $original_line[$i])]
my @genotype = map {[split /:/]} @original_line[6..14]

但这些下面也是合法的吗?很多时候(对我来说)知道代码的其他部分(逻辑)是否导致问题是很困难的。通过parens对我(初学者)进行排序对于良好的编码似乎微不足道。任何关于如何正确使用parens的指南都会很棒。

@{"genotype".[$i]}
@["genotype".($i)]
@("genotype".($i))
@{$genotype($i)}
@[$genotype($i)]
$genotypes[$i] = ( split (/:/, $original_line[$i]))
my @genotype = map ([split /:/]) @original_line[6..14]

2 个答案:

答案 0 :(得分:10)

在Perl中,括号,括号和parens都有多种含义,但花括号可能最多。

  • 的括号
    • 排序优先级2 * 3 + 42 * (3 + 4)
      • 定义函数的参数列表是其中的一个子例:join "", 1, 2, 3join("", 1, 2), 3
      • 带箭头操作符的方法调用的Surround参数列表:$foo->bar(1, 2)(空arglist不需要)
    • 强制解释前一个裸字作为子程序调用。比较Foo->newFoo()->new
    • 使用箭头操作符调用coderefs:$code->()
    • 子程序原型sub foo ($$;$%) { ... }
  • 方括号
    • 数组下标运算符my @array = 1 .. 5; $array[1]
    • Arrayref文字my $aref = [1 .. 5]
  • 大括号
    • 阻止(dosubmapgrep,条件,循环结构,裸块,带标记的块,......)
    • 哈希下标运算符$hash{foo}
    • Hashref文字my $hashref = { a => 3, b => 2 }
    • Dative block print { $filehandles[5] } "Hello world"
    • Circumfix解除引用运算符@{ $aref }%{ $hashref },...
    • 包块package Foo { ... }

...几乎所有字符都可以用作类似引号的运算符q//qq//qr//qx//m//,{{的分隔符1}},s///tr///,带来有趣的内容,例如y///


s(foo){bar}g使用curlies进行符号解除引用,并使用parens(不必要)排除优先级。

@{"genotype".($i)}使用括号作为数组下标运算符,并使用curlies进行解除引用

@{$genotype[$i]}有各种各样的部分:$genotype[$i] = [ split (/:/, $original_line[$i])]$genotype[$i]使用括号进行数组下标。 $original_line[$i]使用括号来创建匿名arrayref。 = [ ... ]中的parens只是界定split(/:/, ...)的参数列表(整理优先级)。

splitmy @genotype = map {[split /:/]} @original_line[6..14]中使用括号作为数组下标运算符,在@original_line[6..14]中使用匿名数组。 curlies用于形成一个块作为[split /:/]的第一个参数。

答案 1 :(得分:1)

map有两种语法

map BLOCK LIST
map EXPR, LIST

在这两种情况下,parens都可以像arg一样在args周围使用。

map(BLOCK LIST)
map(EXPR, LIST)

有一点值得注意的是,虽然LIST可以返回一个空列表,但是它不能完全省略,因为你可以为sub。


map { [split /:/] } @original_line[6..14]

map BLOCK LIST的示例,而

map([split /:/])

非法提供EXPR,但没有LIST。以下是可接受的语法:

map({ [split /:/] } @original_line[6..14])
map { [split /:/] } @original_line[6..14]
map([split /:/], @original_line[6..14])
map [split /:/], @original_line[6..14]

如果表达式类似于(2 + $ _)* 3,则只有以下选项:

map({ (2+$_)*3 } ...)
map { (2+$_)*3 } ...
map((2+$_)*3,  ...)

如果你从最后一个中删除了parens,你最终会得到非法的

map(2+$_)

您可以使用+

消除歧义
map +(2+$_)*3, ...

但最好切换到map BLOCK LIST表示法。