我有一个像这样的Perl文件:
use strict;
f1();
sub f3()
{ f2(); }
sub f1()
{}
sub f2()
{}
简而言之,f1
在定义之前被调用。因此,Perl发出警告:“f1过早地调用原型”。但f2
的情况也是如此,唯一的区别是它是从另一个子程序内部调用的。它不会对f2
发出警告。为什么呢?
解决此问题的最佳方法是什么?
&f1();
答案 0 :(得分:16)
您可以通过不首先使用原型来完全避免此问题:
use strict;
f1();
sub f3 { f2() }
sub f1 {}
sub f2 {}
Don't use prototypes除非你知道为什么要使用它们:
当然,这一切都非常强大,只应在适度的情况下使用才能让世界变得更美好。
答案 1 :(得分:7)
只需从子例程定义中删除()即可。使用()定义时,Perl认为这些是原型,您必须在使用之前定义原型。
试试这个......
use strict;
f1();
sub f3
{ f2(); }
sub f1
{}
sub f2
{}
答案 2 :(得分:2)
来自f2()
的{{1}}来电时没有发出警告似乎是一个错误。
f3()
打印“a”。如果您预先声明use strict;
use warnings;
f1();
sub f1 {
my @a = qw(a b c);
f2(@a);
}
sub f2(\@) { print $_[0] }
或交换子例程定义的顺序,则会打印“ARRAY(0x182c054)”。
至于解决问题,取决于。我的偏好(按顺序)将是:
f2()
表示法调用子程序以绕过原型检查。答案 3 :(得分:2)
如果你打算用括号称它,为什么你甚至使用原型?
sub f1(){ ... }
f1();
我唯一一次使用空原型是为了一个我希望像常量一样工作的子程序。
sub PI(){ 3.14159 }
print 'I like ', PI, ", don't you?\n";
我实际上建议不要使用Perl 5原型,除非您希望子程序的行为与其他方式不同。
sub rad2deg($){ ... }
say '6.2831 radians is equal to ', rad2deg 6.2831, " degrees, of course.\n";
在此示例中,如果没有原型,则必须使用括号。否则它会得到一个额外的参数,最后一个字符串永远不会打印出来。
答案 4 :(得分:2)
在Perl中定义函数时,不应使用括号。当您这样做时,您会收到此错误。 这是错的:
sub DoSomthing(){
#do what ever...
}
这是要走的路:
sub DoSomthing{
#do what ever...
}
没有括号。
有关更详细的表达式,请参阅Gabor Szabo关于Perl中子例程和函数的Perl Maven页面。 https://perlmaven.com/subroutines-and-functions-in-perl
答案 5 :(得分:0)
你可以像C语言一样先声明它。
sub test($);
test("xx");
sub test($) {
# do something
}