Perl 函数 参数 $$, $$$,$@

看到有perl 代码 里面这样写的:
sub a($$)
sub b($$$)
sub c($@)

想问问 这里跟在括号里的参数,是什么意思?先谢过了
甚至还有这种写法:
sub d($$$$$)

Perl 可以通过函数元型在编译期进行有限的参数类型检验。如果你声明

sub mypush (+@)

那么 mypush() 对参数的处理就同内置的 push() 完全一样了。函数声明必须要在编译
相应函数调用之前告知编译器(编译器在编译函数调用时会对相应函数用 prototype
来查询它的元型来进行参数检验,并决定怎样编译此函数调用)。元型只在不用 & 调用
函数的时候起作用。就是说在语法上如果你想像内置函数一样调用,它就表现的像
内置函数一样。如果想用过时的风格通过 & 调用,那么编译器就无视函数声明。另外
元型在函数引用如 \&foo 和间接调用如 &{$subref} 和 $subref->() 时也不起作用。

方法调用也不受元型影响,因为实际调用的函数无法在编译期决定,它是由继承关系
决定的。

因为这个特性最初的目的是使你可以像内置函数那样调用自己的函数,所以下面就给出
等价于内置函数调用方式的函数元型。

声明为 调用方式

sub mylink ($$) mylink $old, $new
sub myvec ($$$) myvec $var, $offset, 1
sub myindex ($$;$) myindex &getstring, "substr"
sub mysyswrite ($$$;$) mysyswrite $buf, 0, length($buf) - $off, $off
sub myreverse (@) myreverse $a, $b, $c
sub myjoin ($@) myjoin ':', $a, $b, $c
sub mypop (+) mypop @array
sub mysplice (+$$@) mysplice @array, 0, 2, @pushme
sub mykeys (+) mykeys %{$hashref}
sub myopen (*;$) myopen HANDLE, $name
sub mypipe (**) mypipe READHANDLE, WRITEHANDLE
sub mygrep (&@) mygrep { /foo/ } $a, $b, $c
sub myrand (;$) myrand 42
sub mytime () mytime

任何 \ 跟着的函数元型中的字符代表着实际的参数必须由相应字符开头(参数前可跟
my our local 声明),只有 $ 例外,它可以接收并不以 $ 开头的 hash 和数组的元素,
比如 my_function()->[0]。传给 @_ 的参数将会是相应实际参数的引用,即对它加 \。

你可以用 \[] 来表示多个可用的类型。比如:

sub myref (\[$@%&*])

上面的函数声明允许像下面这样调用 myref() 这个函数

myref $var
myref @array
myref %hash
myref &sub
myref *glob

传入函数 myref 的第一个参数将分别是一个 scalar、数组、hash、函数、glob 的引用。

函数元型中前面不跟 \ 的字符有特殊意义。任何不跟 \ 的 @ % 将代表剩下的所有参数,
并提供 list context。而 $ 将提供 scalar context。 & 表示需要一个匿名函数(即
sub { } 这样的结构,不能是变量),当用作第一个参数时可以省掉 sub 关键字(如果
省掉 sub 则后面跟的逗号也必须要省掉).

* 表明可以接收一个 bareword、常量、scalar 表达式、typeglob或 typeglob 的引用。
传入函数的参数要么是一个简单的 scalar 要么是 typeglob 的引用(后两种情况)。如果
你总是想要一个 typeglob 的引用可以用 Symbol::qualify_to_ref() 将名字转换成相应
的 typeglob 的引用:

use symbol 'qualify_to_ref';

sub foo (*) {
my $fh = qualify_to_ref(shift, caller);
...
}

+ 类似于 $ 但是当遇到数组变量或 hash 变量时表示 \[@%],在其它情况下总是提供
scalar context。它适用于可以接收数组变量或数组引用为参数的函数:

sub mypush (+@) { # 5.14 中 push 第一个参数可以为数组的引用
my $aref = shift;
die "Not an arrayref" unless ref $aref eq 'ARRAY';
push @$aref, @_;
}

当用 + 时函数必须要检验实际的参数是否是自己需要的类型,因为它不区分 @ %。

分号 ; 用来分隔必须的参数和可选的参数。它必须在 @ % 之前,因为它们代表剩下的
所有参数。

在元型最后或在 ; 之前可以用 _ 来代替 $:它表示如果没有提供这个参数会传递 $_
作为对应的参数,它可以用来实现默认参数的语法。

注意上面列表最后3个例子,mygrep() 表现的就像列表操作符,myrand() 表现的就像
rand() 一样为一元操作符,mytime() 就像 time() 一样完全不需要参数。如果你这么用:

mytime + 2;

你将会得到 mytime() + 2,而不是 mytime(2),没有函数元型根本无法实现这样的效果。

有意思的是你可以把 & 用在最开始的位置来创造新语法:

sub try (&@) {
my ($try, $catch) = @_;
eval { &$try };
if ($@) {
local $_ = $@;
&$catch;
}
}

sub catch (&) { $_[0] }

try {
die "phooey";
} catch {
/phooey/ and print "unphooey\n";
};

上面的代码会打印 "unphooey",即是 Try::Tiny 的实现方法。(当然用 &$catch 会
将 @_ 暴露给 $catch 但这里并不是我们要考虑的)。

让我们重新实现下 Perl 的 grep 操作符:

sub mygrep (&@) { # 无法实现 grep EXPR,LIST 这个语法
my $code = shift;
my @result;
foreach $_ (@_) {
push @result, $_ if &$code;
}
@result;
}

请不在要函数元型中使用字母或数字,它们被保留作它用,或许在将来用于实现完整的
参数列表。不要为老的代码添加上函数元型,因为有时会改变语意出来奇怪的结果。比如:

sub func ($) {
my $n = shift;
print "you ave me $n\n";
}

某人在代码中这么调用它:

func(@foo);
func(split /:/);

只是声明了函数 func 只接收一个 scalar 参数却带来了灾难性的结果,原来参数所处的
list context 被改为 scalar context,传入的参数变成 @foo 的元素个数,和分割的
元素个数。

元型很强大也很危险,请小心慎用。
温馨提示:内容为网友见解,仅供参考
无其他回答

Perl 函数 参数 $$, $$$,$@
Perl 可以通过函数元型在编译期进行有限的参数类型检验。如果你声明 sub mypush (+@)那么 mypush() 对参数的处理就同内置的 push() 完全一样了。函数声明必须要在编译 相应函数调用之前告知编译器(编译器在编译函数调用时会对相应函数用 prototype 来查询它的元型来进行参数检验,并决定怎样编译此函...

Perl中的特殊变量入门和高级技巧
是异常处理变量,它记录最近发生的错误信息。当使用eval函数处理可能出错的代码时,任何错误都会存储在$@中,通过检查其是否为空可以判断是否有错误,进一步处理错误信息。!则用于存储系统调用的错误信息,当使用Perl函数执行操作系统操作时,如打开文件或执行命令,若出现系统级错误,$!会保存错误编号,用于识...

Perl中的默认变量@_和$_什么意思?
chomp($_)以下是几处即使没有写明 Perl 也会假定使用 $_ 的地方:各种单目函数,包括像 ord() 和 int() 这样的函数以及除 "-t"以外所有的文件 测试操作 ("-f","-d"),"-t" 默认操作 STDIN。各种列表函数,例如 print() 和 unlink()。没有使用 "=~" 运算符时的模式匹配操作 "m\/\/...

perl @_ $_ 是什么意思啊
1.@_ 是函数传参时放置参数的数组,可以从中取实参,比如 my($para1,$para2...)=@_, 函数调用时填了几个参数,便可以从该数组中取到几个参数。2.$_ 是默认参数的意思,指的是在不指定的情况下,程序处理的上一个变量,比如 open(IN,"<file.txt")while(<IN>){ print $_;} close(IN...

【perl】基本语法三
Perl交换两个变量可通过列表赋值实现。foreach循环用于遍历数组元素。`pop`从数组后面删除元素,`push`在数组后面添加数据,`shift`从数组前面删除数据,`unshift`则从数组前面添加数据。`splice`函数可以在数组中间进行操作,共有四个参数:要操作的目标数组、操作开始的位置、操作长度以及需要插入的变量或...

变量前面有个$是什么意思?
一,是如上所说的,一些perl,php出身的,习惯写js用$函数代表dom 二,是一些现在流行的通用框架,都是基于$符号的,有些程序JS框架用了这些,所以通篇都是$,你可以搜下prototyppe,jquery,mootools这些

perl 中$_
有很多的,大多系统提供的函数都有把。chop,chomp...

perl,两个正则匹配脚本比较:
第一个是数组,存储了匹配的每一个字串,在例子中除了5都 是的,而$&只是返回最近的成功匹配的字串,第一个字就匹配成功,if为真然后打印出来匹配成功的字串 Fred

perl 数据分解及转换
perl 定义一个变量要以$符开头,应该是my $solt 第一个可以用正则表达式替换s\/[a-z](\\d)*\/$2\/ 第二个用split函数 @array=split \/R\/,$solt;

Perl函数参数的传递 和 函数参数中多个数组怎么传递
首先来个基本函数参数的传递 sub hello { print "Hello @_" }hello ("World!", "I am Robot" ) ; # 打印出 Hello World! I am Robot这里值得留意的就是 @_ 就是装载所有传入的参数的数组 ( 看好了, 这其实是数组啊!! )所以, 将上面的改一下, 就可以:sub hello { print "Hello ...

相似回答