我看到了一些像这样的代码〜
my @array = @{ $array_ref };
Run Code Online (Sandbox Code Playgroud)
我发现如果我把它改成〜它的工作原理是一样的
my @array = @$array_ref;
Run Code Online (Sandbox Code Playgroud)
同样,这个〜
my %hash = (frogs => sub {print "Frogs\n"});
&{$hash{frogs}}();
Run Code Online (Sandbox Code Playgroud)
与〜一样工作
%hash = (frogs => sub {print "Frogs\n"});
$hash{frogs}();
Run Code Online (Sandbox Code Playgroud)
(虽然我最初尝试过,因为&hash{frogs}();期望它能够工作,但由于产生的错误我不明白 - 这个sigil是否应该与哈希中访问的东西相对应,在这种情况下&对于子程序?)
所以我想知道为什么这些片段的作者会以另一种方式编写它们,当它是额外的字符而没有我能感知到的任何优势时.
在这里发生的事情我没有注意到吗?什么时候你可能需要使用花括号而不仅仅是sigil?
你在混淆两个概念.
"Block syntax" "Arrow syntax"
$BLOCK EXPR->$*
@BLOCK EXPR->@*
$BLOCK[$i] EXPR->[$i]
&BLOCK() EXPR->()
... ...
Run Code Online (Sandbox Code Playgroud)
此外,两种语法都可以使用它们.
您的数组示例是块语法可用的简化示例.如果块只包含一个简单的标量($ref),则可以省略curlies.
${ $ref } # Can be simplified to $$ref
@{ $ref } # Can be simplified to @$ref
${ $ref }[$i] # Can be simplified to $$ref[$i]
&{ $ref }() # Can be simplified to &$ref()
Run Code Online (Sandbox Code Playgroud)
如果该块包含其他任何内容,则无法利用此简化.
@{ $refs{$key} } # Can't be simplified
@{ f() } # Can't be simplified
@{ my $ref = f(); $ref } # Can't be simplified
&{ $refs{$key} }() # Can't be simplified
&{ f() }() # Can't be simplified
&{ my $ref = f(); $ref } # Can't be simplified
Run Code Online (Sandbox Code Playgroud)
另一方面,您的代码示例是从块语法切换到箭头语法的示例.这本身并不简单.
"Block syntax" "Arrow syntax"
&{ $hash{frogs} }() ? $hash{frogs}->()
Run Code Online (Sandbox Code Playgroud)
您的代码示例也是箭头语法可用的简化示例.当箭头之间[...]或{...},和[...],{...}或(...),箭头可以省略.
$ref->{$k}->[$i] # Can be simplified to $ref->{$k}[$i]
$ref->{$k}->{$l} # Can be simplified to $ref->{$k}{$l}
$ref->{$k}->() # Can be simplified to $ref->{$k}()
$ref->[$i]->[$j] # Can be simplified to $ref->[$i][$j]
$ref->[$i]->{$k} # Can be simplified to $ref->[$i]{$k}
$ref->[$i]->() # Can be simplified to $ref->[$i]()
Run Code Online (Sandbox Code Playgroud)
最后,你应该使用哪个?
是否对块语法或箭头语法的选择是个人偏好之一,但通常遵循以下约定以最大化可读性:
块语法是标量,数组和散列解引用的首选.
$$ref is generally preferred over $ref->$*
@$ref is generally preferred over $ref->@*
%$ref is generally preferred over $ref->%*
Run Code Online (Sandbox Code Playgroud)使用块语法时,如果可能,将省略curlies.
$$ref is generally preferred over ${ $ref }
@$ref is generally preferred over @{ $ref }
%$ref is generally preferred over %{ $ref }
Run Code Online (Sandbox Code Playgroud)箭头语法是数组元素,哈希元素和代码解引用的首选.
$ref->[...] is generally preferred over $$ref[...]
$ref->{...} is generally preferred over $$ref{...}
$ref->(...) is generally preferred over &$ref(...)
Run Code Online (Sandbox Code Playgroud)尽可能省略箭头本身,除非用于参考代码.
$ref->[...][...] is generally preferred over $ref->[...]->[...]
$ref->[...]{...} is generally preferred over $ref->[...]->{...}
$ref->[...]->(...) is generally preferred over $ref->[...](...)
$ref->{...}[...] is generally preferred over $ref->{...}->[...]
$ref->{...}{...} is generally preferred over $ref->{...}->{...}
$ref->{...}->(...) is generally preferred over $ref->{...}(...)
Run Code Online (Sandbox Code Playgroud)块语法是数组切片和散列切片的首选.它的可读性远远低于箭头语法,但这些箭头语法需要Perl 5.24.
@$ref[...] is generally preferred over $ref->@[...]
@$ref{...} is generally preferred over $ref->@{...}
Run Code Online (Sandbox Code Playgroud)