我可以知道&在没有它的情况下底部的使用是什么,潜艇仍然可以运行.
而且,my在perl变量前面.
我知道它是用于严格的语言语法或者不是,但是为什么不将它们作为一个标准,每个变量都需要由a声明my?
编辑
感谢您的所有讨论/答案,我希望接受您的许多答案,但由于我只能接受一个答案,我将接受其他用户可能轻松理解的答案.
Eri*_*rom 12
在Perl中,函数调用已经过优化,不需要&始终使用sigil.声明子例程时:
sub hello {print "world\n"}
Run Code Online (Sandbox Code Playgroud)
你可以把它作为hello;或hello();或&hello();将都做同样的事情.
如果你的子程序有参数,那就有点不同了:
sub hello {print "Hello, @_!\n"}
hello 'World'; # prints 'Hello, World!'
hello('World'); # same
&hello('World'); # same
hello; # prints 'Hello, !'
&hello(); # same
&hello; # different, uses whatever was in @_ when hello was called
@_ = 'Bob';
hello; # prints 'Hello, !'
&hello(); # prints 'Hello, !'
&hello; # prints 'Hello, Bob!'
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,&除了没有参数列表的情况外,使用sigil在很大程度上是多余的.在这种情况下,使用当前值调用子例程@_.
该&印记还有另一种与Perl原型相关的特殊行为.假设您正在编写自己的keys函数,并希望它的行为类似于Perl:
sub mykeys (\%) {keys %{$_[0]}}
Run Code Online (Sandbox Code Playgroud)
这里的(\%)原型告诉perl第一个参数mykeys必须是一个文字哈希(它将作为哈希引用传入).
my $hashref = {...};
say for mykeys %$hashref;
Run Code Online (Sandbox Code Playgroud)
如果由于某种原因你需要绕过这个要求(通常不是最好的想法),你可以这样写:
say for &mykeys( $hashref ); # note that there is no `%`
Run Code Online (Sandbox Code Playgroud)
在这种情况下,&在sub之前添加禁用原型检查以及它将执行的任何后续操作(如获取引用).在这种用法中,&基本上是一个断言,你确切知道什么参数mykeys需要,并且你不希望perl妨碍.
通常,&应该避免使用on子例程,除非您明确地想要我上面提到的行为之一.
最后,&在您引用实际代码引用时也需要:
my $coderef = \&hello;
Run Code Online (Sandbox Code Playgroud)
要么
if (defined &hello) {print "hello is defined\n"} # but is not called
Run Code Online (Sandbox Code Playgroud)
正如其他人所提到的,my运算符在当前词法范围内声明变量.use strict;加载编译指示时需要它.Perl有两种类型的变量,声明的词法变量my和包变量.
my变量存在于所谓的词法填充中,这是每次引入新作用域时由Perl创建的存储空间.包变量存在于全局符号表中.
use strict;
use warnings;
$main::foo = 5; # package variable
{ # scope start
my $foo = 6;
print "$foo, $main::foo\n"; # prints '6, 5';
} # scope end
print "$foo, $main::foo\n"; # syntax error, variable $foo is not declared
Run Code Online (Sandbox Code Playgroud)
您可以使用our关键字为全局变量创建词法别名:
use strict;
our $foo = 5; # $main::foo == $foo
{ # scope start
my $foo = 6;
print "$foo, $main::foo\n"; # prints '6, 5';
} # scope end
print "$foo, $main::foo\n"; # prints '5, 5'
# since $foo and $main::foo are the same
Run Code Online (Sandbox Code Playgroud)
将my变量限制为当前范围.使用use strict您应该使用的pragma,您必须声明变量(例如with my).由于非常短的脚本的灵活性原因,存在替代方案.
在&因为Perl默认解释印记,少言的子程序很少再使用,但如果你想创建到子过程的引用是非常有用的.
sub say_hi { print "hi\n" }
my $sub_ref = \&say_hi;
Run Code Online (Sandbox Code Playgroud)
我可以知道在没有它的情况下在潜艇前面使用了什么,潜艇仍然可以运行.
向后兼容Perl 4
而且,我在perl变量面前.
它设置了块范围
我知道它是用于严格的语言语法或者不是,但是为什么它们只是使它成为一个标准,每个变量都需要由我声明?
use strict;不允许使用裸变量声明)our或声明local