12

做了一些搜索,但找不到任何有用的东西。我想知道是否有一个排序汇总表供初学者了解使用括号/括号的“规则”,特别是 ()、[]、{} 之间的区别。不幸的是,根据我的经验,如果我使用了错误的括号use strictuse warnings请不要告诉我。

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

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

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

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

2 回答 2

12

在 Perl 中,方括号、大括号和括号都有多种含义,但花括号可能是最多的。

  • 帕伦斯
    • 排序优先级2 * 3 + 42 * (3 + 4)..
      • 为函数分隔参数列表是这种情况的一个子案例:join "", 1, 2, 3vs.join("", 1, 2), 3
      • 使用箭头运算符包围方法调用的参数列表:($foo->bar(1, 2)空 arglist 不需要)
    • 强制将前一个裸字解释为子例程调用。比较Foo->newFoo()->new
    • 使用箭头运算符调用 coderefs:$code->()
    • 子程序原型sub foo ($$;$%) { ... }
  • 方括号
    • 数组下标运算符my @array = 1 .. 5; $array[1]
    • Arrayref 字面量my $aref = [1 .. 5]
  • 大括号
    • 块 (for do, sub, map, grep, 条件, 循环结构, 裸块, 标记块, ... )
    • 哈希下标运算符$hash{foo}
    • Hashref 字面量my $hashref = { a => 3, b => 2 }
    • 与格print { $filehandles[5] } "Hello world"
    • Circumfix 取消引用运算符@{ $aref }, %{ $hashref }, ...
    • 封装块package Foo { ... }

......几乎所有字符都可以用作类似引号的运算符的分隔符q//, qq//, qr//, qx//, m//, s///, tr///, y///, 导致有趣的东西,比如s(foo){bar}g


@{"genotype".($i)}使用 curlies 进行符号取消引用,并使用 parens 来(不必要地)整理优先级。

@{$genotype[$i]}使用方括号作为数组下标运算符,并使用 curlies 来取消引用

$genotype[$i] = [ split (/:/, $original_line[$i])]有不同的部分:$genotype[$i]$original_line[$i]使用括号进行数组下标。使用= [ ... ]方括号来创建匿名数组引用。括号中的split(/:/, ...)只是分隔参数列表split(排序优先级)。

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

于 2013-04-22T18:28:41.877 回答
2

map有两种语法

map BLOCK LIST
map EXPR, LIST

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

map(BLOCK LIST)
map(EXPR, LIST)

需要注意的一点是,虽然 LIST 可以返回一个空列表,但不能像对 subs 一样完全省略它。


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,  ...)

如果你从最后一个删除括号,你最终会得到非法的

map(2+$_)

您可以使用消除歧义+

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

但最好切换到map BLOCK LIST符号。

于 2013-04-22T18:20:22.463 回答