Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl函数声明_Perl_Prototype_Declaration - Fatal编程技术网

Perl函数声明

Perl函数声明,perl,prototype,declaration,Perl,Prototype,Declaration,这是一个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行): 据我所知,这是因为函数被设置为返回某些内容,但当我声明它时,它被声明为“vo

这是一个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行):

据我所知,这是因为函数被设置为返回某些内容,但当我声明它时,它被声明为“void”

我如何声明下面这样的函数

sub remCH(string/integer);
  • 您只需删除#1行中的函数声明(或Perl中的“”即可)。您的错误是因为原型(
    remCH()
    )声明函数具有“零参数”签名,而您的调用只传递一个参数。返回类型与此无关

    Perl中有一些原型的有效用例,但除非您知道为什么要这样设计代码,否则经验法则是永远不要使用原型。请参阅以下帖子:

  • 另外,根据plusplus的明智评论,我没有注意到第5行的函数定义中有“()”。与C不同,Perl中不需要它们-请删除它们。他们将函数定义转化为另一个原型


尽管如此:

  • 您可以使用
    remCH($)
    prototype来原型化接受1个标量参数的子对象
  • 您可以通过切换到面向对象的Moose框架来检查它们的类型

  • 与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不接受任何参数:
      sub foo()
      ,等等
    不要使用这些来验证参数的数量。实际上,根本不用它们;它们在远处引起作用。它们对于类型验证也没有用处

    您的错误源于您将sub声明为空,这导致了一个解析错误


    如果希望能够使用命名参数声明子例程,可以使用实现这些参数的模块。有几点需要注意:

    • 这些模块并不普遍,所以只在可移植性不成问题的内部项目中使用它们
    • 它们只在较新的管道上工作
    • 他们经常弄乱你的行号:(
    一个好的实现是
    Method::Signatures
    ,它还允许类型(和值)验证:

    use Method::Signatures;
    
    my $sum = add(1, 2);
    
    func add(Int $x, Int $y) {
      return $x + $y;
    }
    

    但是,这些“签名”与普通sub的原型无关。

    所以要翻译你刚才说的话,我应该删除第一行,我应该没事,对吧?:删除第二个函数声明中的原型,使其成为
    sub remCH{
    …@user2493988-另外,正如plusplus正确指出的那样,去掉第5行的括号。这些括号构成了第二个原型。C语法不同于Perl的语法谢谢你解释。我想我将走一小段路,删除subs的所有预声明
    use Method::Signatures;
    
    my $sum = add(1, 2);
    
    func add(Int $x, Int $y) {
      return $x + $y;
    }