perl-子程序

自从学完reference就感觉轻松了不少!

subroutine

子程序(函数):

  • 一个代码块。A Perl function or subroutine is a group of statements that together perform a specific task
  • perl中可以放到任意位置,并不像shell中必须放到最开头。还可以跨文件访问:使用usedorequire

语法:

1
sub NAME  PROTOTYPES ATTRIBUTES BLOCK
  1. sub:表示这是一个函数

  2. name:函数名称,它有自己独立的命名空间,所以可以使用已有的标量变量的名称,并不冲突。

    1
    2
    3
    eg:
    $scale = 'iu';
    sub scale = {....}
  3. prototypes:函数期望什么参数,并不常用

  4. attribute:属性,包含了locked, methodand lvalue,并不常用

  5. block:放函数主体

1
2
3
sub say_something{
print "Hi, this is the first subroutine\n";
}

调用:

使用&subroutine_name或者subroutine_name()

1
2
&say_something;
say_something();

但是&更为通用,比如说在reference时:

1
$say_somethingRef = \&say_something;

dereference:

1
&\$say_somethingRef

传参

1
2
3
4
5
sub test{
foreach (@_){
print $_,"\n";
}
}

使用&subroutine_name写法时:

1
2
# 直接将参数传过去,其它的写法不行
&test(1..9);

使用subroutine_name()写法时:

1
2
3
4
5
6
7
8
9
10
11
12
# 各种都支持
# 直接传参数
test(1..9);
# 通过数组
@list = (1..9);
test(@list);
# 通过reference
$list = \@list;
test($list);
# 通过dereference
$list = \@list;
test(@$list);

注意点:

  1. 由于在函数外定义的变量为全局变量,所以如果在函数中对其数据就行了修改,会影响原始数据,这个与python差别就很大了。这被称为通过reference传值

    1
    2
    3
    sub getreference{
    $_[0] = 'iu';
    }
  1. 那么如何避免修改函数外部的变量,定义函数内部的变量,将函数外部传进来的值重新变为函数内部的。这被称为通过value传值

    1
    2
    3
    sub getvalue{
    my @list = @_;
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/perl
# 将两个列表合并为一个

@one = (1,2,3,4,5);
@two = (6,7,8,9,10);
sub conn{
foreach (@_){
push(@three,$_);
}
return @three;
}

@list = conn(@one,@two);
print @list,"\n";

当然,如果要是合并两个数组,并不需要这么写,可以直接合并

1
2
3
@one = (1,2,3,4,5);
@two = (6,7,8,9,10);
@there = (@one,@two);

返回值

  1. 默认返回最后一个执行的语句。不需要写return

    1
    2
    3
    4
    5
    6
    print &say_hi , "\n";
    sub say_hi{
    my $name = 'Bob';
    print "Hi $name \n";
    $name; #默认返回这个语句
    }
  1. 也可以使用return来显式的说明要返回值,return可以写在函数内部任意位置,但是return之后的语句不会执行

    1
    2
    3
    4
    5
    sub say_hi{
    my $name = 'Bob';
    print "Hi $name \n";
    return $name; #用return返回值
    }

参数校验

我们一般会在函数中对传进来的值进行校验,如果不存在那么就返回一个undef,可以配合调用函数时的if检测是否传值正确。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/perl

sub test{
#使用shift取到一个参数
$arg = shift;
#进行判断
return undef unless defined $arg;
foreach (@_){
print $_,"\n";
}
}


@list = (1..9);
$test = test(@list);
if(defined $test){
print $test;
}
else{
print "undeined";
}
# 也可以简化写为
print $test if(defined $test);