这是一个Perl n00b问题,但我没有找到一个清晰易懂的在线回答。
我有这段代码:
1.sub remCH();
2.#some stuff
3.$line = remCH($line);
4.
5.sub remCH() {
6.$rem = shift;
7.$rem = chomp($rem);
8.return ($rem);
9.}
执行此代码时,我总是遇到以下错误(第24行将在上面的代码中为第3行):
Too many arguments for main::rem_CRLF at ./make_csv.pl line 24, near "$line)"
根据我的理解,这是因为函数设置为返回一些东西但是当我声明它时,它被声明为“void”。
如何声明如下函数???
sub remCH(string/integer);
答案 0 :(得分:6)
您应该只是删除第1行中的函数声明(或Perl中已知的“prototype”)。您的错误是因为原型(remCH()
)声明函数具有“零参数”签名,而您的调用将其传递给一个参数。返回类型与它无关。
在Perl中有一些有效的原型用例,但除非你知道为什么要用这种方式设计代码,否则经验法则是永远不要使用原型。见SO帖子:
另外,根据plusplus的明智评论,我错过了你在第5行的函数定义中有“()”。与C不同,你在Perl中不需要它们 - 请放弃它们。他们将函数定义转换为另一个原型。
说完了:
remCH($)
原型 答案 1 :(得分:4)
与其他语言(如C:
)不同,Perl没有类型签名或形式参数// C code
int add(int, int);
int sum = add(1, 2);
int add(int x, int y) {
return x + y;
}
相反,参数只是作为一个平面列表传递。任何类型验证都发生在您的代码中;你必须手动写这个。您必须自己将arglist解压缩到命名变量中。而且您通常不预先声明子例程:
my $sum = add(1, 2);
sub add {
my ($x, $y) = @_; # unpack arguments
return $x + $y;
}
如果你预先确定你的潜艇,你会得到以下结果:
原型可以说
sub foo($)
或sub foo(\%)
或sub foo()
等等。请勿使用这些来验证参数的数量。实际上,根本不要使用它们;他们在远处引起行动。它们也不适用于类型验证。
您的错误源于您将sub声明为nullary,这导致解析错误。
如果您希望能够使用命名参数声明子例程,则可以使用实现这些参数的模块。有几点需要注意:
一个好的实现是Method::Signatures
,它还允许类型(和值)验证:
use Method::Signatures;
my $sum = add(1, 2);
func add(Int $x, Int $y) {
return $x + $y;
}
然而,这些“签名”与普通潜艇的原型没有没有。