我有一个这样的 Perl 文件:
use strict;
f1();
sub f3()
{ f2(); }
sub f1()
{}
sub f2()
{}
简而言之,f1
在定义之前被调用。因此,Perl 抛出一个警告:“f1 调用太早,无法检查原型”。但情况也是如此f2
,唯一的区别是它是从另一个子例程内部调用的。它不会为f2
. 为什么?
解决此问题的最佳方法是什么?
- 在调用子程序之前声明它
- 像这样调用子:
&f1();
我有一个这样的 Perl 文件:
use strict;
f1();
sub f3()
{ f2(); }
sub f1()
{}
sub f2()
{}
简而言之,f1
在定义之前被调用。因此,Perl 抛出一个警告:“f1 调用太早,无法检查原型”。但情况也是如此f2
,唯一的区别是它是从另一个子例程内部调用的。它不会为f2
. 为什么?
解决此问题的最佳方法是什么?
&f1();
You can completely avoid this issue by not using prototypes in the first place:
use strict;
f1();
sub f3 { f2() }
sub f1 {}
sub f2 {}
Don't use prototypes unless you know why you are using them:
This is all very powerful, of course, and should be used only in moderation to make the world a better place.
只需从您的子例程定义中删除 ()。当你用 () 定义时,Perl 认为这些是原型,你必须在使用它之前定义你的原型。
尝试这个:
use strict;
f1();
sub f3
{ f2(); }
sub f1
{}
sub f2
{}
在 Perl 中定义函数时,不应使用括号。当你这样做时,你会得到这个错误。这是错误的:
sub DoSomthing(){
#do what ever...
}
这是要走的路:
sub DoSomthing{
#do what ever...
}
没有括号。
有关更详细的说明,请参阅 Gabor Szabo 的 Perl Maven 页面,了解 Perl 中的子例程和函数。 https://perlmaven.com/subroutines-and-functions-in-perl
对f2()
from的调用缺少警告f3()
似乎是一个错误。
use strict;
use warnings;
f1();
sub f1 {
my @a = qw(a b c);
f2(@a);
}
sub f2(\@) { print $_[0] }
这将打印“a”。如果您预先声明f2()
或交换子例程定义的顺序,它会打印“ARRAY(0x182c054)”。
至于解决情况,就看情况了。我的偏好(按顺序)是:
&foo()
以绕过原型检查。如果你要用括号来调用它,你为什么还要使用原型?
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";
在此示例中,如果没有原型,则必须使用括号。否则它会得到一个额外的参数,并且最后一个字符串永远不会被打印出来。
你可以像 C 语言一样先声明它。
sub test($);
test("xx");
sub test($) {
# do something
}