Perl函数原型
通过原型定义程序员自己的函数,可以像Perl内置函数一样调用自己的函数。
原型对参数的个数,参数的类型等做各种约束。使用原型定义函数,函数更安全更好用。
下面是本人对函数原型的理解,仅供交流学习。
Perl原型是什么
按照基本方式定义mypush
子例程
sub mypush {
my @array = @_;
...
...
}
调用mypush @array, $item;
,
如果子例程传入的第一个参数是数组@,则不管之后有多少实参,此刻都是列表上下文,所有参数组成一个列表,子例程得到一个新列表[@array, $item, ...]
,这无法对@array
修改,因此必须传入一个数组引用才可以,我们优化mypush
函数。
优化的mypush
函数
sub mypush {
my ($array, $item) = @_;
return unless ( ref($array) eq ref([]) ); ## $array接收一个数组引用
...
...
}
现在调用mypush \@array, $item;
,用反斜线\
传入数组的引用,mypush
可以对数组进行修改。然而每次调用都需要反斜线引用。
用原型定义mypush
sub mypush (+@) {
my $ref = shift;
my $index = scalar @$ref;
for(@_) {
$$ref[$index++] = $_;
}
$scalar @$ref;
}
使用+@
定义mypush,现在调用mypush @array, $item;
mypush \@array, $itme1, $item2;
mypush @array, $item1, $item2;
都能对@array
修改增加元素,且原型能对参数进行类型检测。
通过使用原型定义的子例程,按规则对参数进行增强或者约束,这就是原型的作用。
原型有哪些
使用原型声明子例程的格式为
sub func (+@) { // `+@`是原型的一种
...
}
原型的种类有如下几种
\ ## 提供引用
$ ## 标量上下文
@ ## array,列表上下文
% ## hash,列表上下文
[] ## 多选一,和在正则表达式中一样
; ## 必选参数和可选参数的分隔符
_ ## 原型的最后一个字符或分号前的字符可用_代替$,如果没有提供该参数,默认读入当前$_
& ## 要求参数为\&foo或sub{},作为第一个参数时,可省略sub
+ ## 是$的特殊代替选项;可接受直接量数组、散列,将其解析为引用;也可接受数组、散列的引用
* ## 可接受文件句柄参数,包括裸名、常量、标量表达式、类型团和类型团的引用
使用原型
声明 | 调用 | 理解 |
---|---|---|
sub mylink ($$) | mylink $old, $new | 将参数解析为在标量上下文中的值,两个值 |
sub myreverse (@) | myreverse $a,$b,$c | 将参数解析为LIST,提供列表上下文环境 |
sub myjoin ($@) | myjoin “:”,$a,$b,$c | 第一个参数解析为标量值,其他参数解析为LIST |
sub mypop (;+) | mypop @array | 没有必要参数,可选参数为’+’能接受的所有值 |
sub mysplice (+;$$@) | mysplice @array,@array,0,@pushme | 必要参数解析为\@array ,可选参数解析为scalar @array, 0, @alist |
sub mykeys (+) | mykeys %{$hashref} | ‘+’标量值解析为标量值,数组或散列解析为引用 |
sub mypipe (**) | mypipe READHANDLE, WRITEHANDLE | 将参数解析为文件句柄 |
sub myindex ($$;$) | myindex &getstring, “substr” | &getstring 解析为标量上下文中的返回值,其他选项解析为标量 |
- | myindex &getstring, “substr”, $start | |
sub mysyswrite (*$;$$) | mysyswrite OUTF, $buf | 必要选项解析为文件句柄和标量值 |
- | mysyswrite OUTF, $buf, length($buf)–$off, $off | 可选选项解析为标量值 |
sub myopen (*;$@) | myopen HANDLE | - |
- | myopen HANDLE, $name | |
- | myopen HANDLE, “–|”, @cmd | |
sub mysin (_) | mysyn $a | 最后一个$字符,可改写为_,$a解析为正常标量 |
- | mysyn | 没有实参时,函数内默认使用当前$_作为_位置的参数 |
sub mygrep (&@) | mygrep { /foo/ } $a,$b,$c | { … }解析为函数引用,解析为LIST |
sub myrand ($) | myrand 42 | |
sub mytime () | mytime | 无参数的函数 |