感谢您的光临! Learnfk在线教程网正在翻译编辑中,请您稍等(v^_^)v Learnfk在线教程网
英文链接源链接 [400]
contenteditable="true"

Perl - Subroutines 介绍

定义并调用Subroutine

Perl编程语言中 Subroutine定义的一般形式如下:

sub subroutine_name {
   body of the subroutine
}

调用该Perl Subroutine的典型方式如下-

subroutine_name( list of arguments );

在Perl 5.0之前的版本中,调用 Subroutine的语法略有不同,如下所示。这仍然可以在Perl的最新版本中使用,但是不建议这样做,因为它会绕过 Subroutine原型。

&subroutine_name( list of arguments );

让我们看下面的Example,该Example定义一个简单的函数然后调用它。由于Perl在执行程序之前先对其进行编译,因此在哪里声明 Subroutine都没有关系。

#!/usr/bin/perl

# Function definition
sub Hello {
   print "Hello, World!\n";
}

# Function call
Hello();

当执行上述程序时,将产生以下输出-

Hello, World!

将参数传递给 Subroutine

您可以像在任何其他编程语言中一样将各种参数传递给 Subroutine,并且可以使用特殊数组@_在函数内部访问它们。因此,函数的第一个参数位于$_ [0]中,第二个参数位于$_ [1]中,依此类推。

让我们尝试以下Example,该Example获取一个数字列表,然后打印其平均值-

#!/usr/bin/perl

# Function definition
sub Average {
   # get total number of arguments passed.
   $n = scalar(@_);
   $sum = 0;

   foreach $item (@_) {
      $sum += $item;
   }
   $average = $sum/$n;

   print "Average for the given numbers : $average\n";
}

# Function call
Average(10, 20, 30);

当执行上述程序时,将产生以下输出-

Average for the given numbers : 20

将List传递给 Subroutine

由于@_变量是一个数组,因此可以用来为 Subroutine提供列表。但是,由于Perl接受并解析列表和数组的方式,可能很难从@_中提取单个元素。如果您必须将列表与其他标量参数一起传递,则将list作为最后一个参数,如下所示-

#!/usr/bin/perl

# Function definition
sub PrintList {
   my @list = @_;
   print "Given list is @list\n";
}
$a = 10;
@b = (1, 2, 3, 4);

# Function call with list parameter
PrintList($a, @b);

当执行上述程序时,将产生以下输出-

Given list is 10 1 2 3 4

将Hashes传递给 Subroutine

当您向接受列表的 Subroutine或运算符提供哈希值时,哈希值将自动转换为键/值对列表。如-

#!/usr/bin/perl

# Function definition
sub PrintHash {
   my (%hash) = @_;

   foreach my $key ( keys %hash ) {
      my $value = $hash{$key};
      print "$key : $value\n";
   }
}
%hash = ('name' => 'Tom', 'age' => 19);

# Function call with hash parameter
PrintHash(%hash);

当执行上述程序时,将产生以下输出-

name : Tom
age : 19

Subroutine返回值

您可以像使用其他任何编程语言一样从 Subroutine返回值。如果您没有从 Subroutine中返回值,那么 Subroutine中最后执行的任何计算都会自动返回值。

让我们尝试以下Example,该Example接受一个数字列表,然后返回其平均值-

#!/usr/bin/perl

# Function definition
sub Average {
   # get total number of arguments passed.
   $n = scalar(@_);
   $sum = 0;

   foreach $item (@_) {
      $sum += $item;
   }
   $average = $sum/$n;

   return $average;
}

# Function call
$num = Average(10, 20, 30);
print "Average for the given numbers : $num\n";

当执行上述程序时,将产生以下输出-

Average for the given numbers : 20

Subroutine中的私有变量

默认情况下,Perl中的所有变量都是全局变量,这意味着可以从程序中的任何位置访问它们。但是您可以随时使用 my 运算符创建称为词法变量的 private 变量。

以下Example显示了如何使用 my 运算符定义单个或多个私有变量-

sub somefunc {
   my $variable; # $variable is invisible outside somefunc()
   my ($another, @an_array, %a_hash); # declaring many variables at once
}

让我们检查以下Example,以区分全局变量和私有变量:

#!/usr/bin/perl

# Global variable
$string = "Hello, World!";

# Function definition
sub PrintHello {
   # Private variable for PrintHello function
   my $string;
   $string = "Hello, Perl!";
   print "Inside the function $string\n";
}
# Function call
PrintHello();
print "Outside the function $string\n";

当执行上述程序时,将产生以下输出-

Inside the function Hello, Perl!
Outside the function Hello, World!

通过local()的临时值

local 通常在变量的当前值必须对所调用的 Subroutine可见时使用。局部变量只是为全局变量(变量包)提供临时值。这就是动态作用域。用my完成词法作用域,它的工作方式更像C的自动声明。

如果将多个变量或表达式赋给local,则必须将它们放在括号中。该运算符的工作方式是将这些变量的当前值保存在其参数列表中的隐藏堆栈中,并在退出块, Subroutine或eval时恢复它们。

让我们检查以下Example以区分全局变量和局部变量-

#!/usr/bin/perl

# Global variable
$string = "Hello, World!";

sub PrintHello {
   # Private variable for PrintHello function
   local $string;
   $string = "Hello, Perl!";
   PrintMe();
   print "Inside the function PrintHello $string\n";
}
sub PrintMe {
   print "Inside the function PrintMe $string\n";
}

# Function call
PrintHello();
print "Outside the function $string\n";

当执行上述程序时,将产生以下输出-

Inside the function PrintMe Hello, Perl!
Inside the function PrintHello Hello, Perl!
Outside the function Hello, World!

通过state()的状态变量

词汇变量还有另一种类型,类似于私有变量,但是它们保持其状态,并且在多次调用 Subroutine时不会重新初始化它们。这些变量是使用 state 运算符定义的,可从Perl 5.9.4开始使用。

让我们检查以下Example以演示 state 变量的用法-

#!/usr/bin/perl

use feature 'state';

sub PrintCount {
   state $count = 0; # initial value

   print "Value of counter is $count\n";
   $count++;
}

for (1..5) {
   PrintCount();
}

当执行上述程序时,将产生以下输出-

Value of counter is 0
Value of counter is 1
Value of counter is 2
Value of counter is 3
Value of counter is 4

在Perl 5.10之前,您必须像这样编写它-

#!/usr/bin/perl

{
   my $count = 0; # initial value

   sub PrintCount {
      print "Value of counter is $count\n";
      $count++;
   }
}

for (1..5) {
   PrintCount();
}

Subroutine调用context

Subroutine或语句的context定义为期望的返回值的类型。这使您可以使用一个函数,该函数根据用户期望接收的内容返回不同的值。如,以下localtime()在标量context中调用时返回一个字符串,但是在列表context中调用时返回一个列表。

my $datestring = localtime( time );

在此Example中,$time的值现在是由当前日期和时间组成的字符串,如Thu Nov 30 15:21:332000。反之

($sec,$min,$hour,$mday,$mon, $year,$wday,$yday,$isdst) = localtime(time);

现在,各个变量包含由localtime() Subroutine返回的相应值。

点我分享笔记