加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Learning Perl 8

发布时间:2020-12-16 00:36:05 所属栏目:大数据 来源:网络整理
导读:符号引用 ? ? 一般来说,类似$$var的结构表示,$var是一个引用变量,而且程序员希望该表达式能够返回$var所指向的值。 假如$var不是引用变量的话会出现什么情况呢?Perl并不是断然打印出错误信息,而是尝试检查$var的值是否为一字符串。如果是,Perl将以该字

符号引用

? ? 一般来说,类似$$var的结构表示,$var是一个引用变量,而且程序员希望该表达式能够返回$var所指向的值。
假如$var不是引用变量的话会出现什么情况呢?Perl并不是断然打印出错误信息,而是尝试检查$var的值是否为一字符串。如果是,Perl将以该字符串作为正规的变量名与这个变量重新加以组合!考虑下面的例子:
#!/usr/bin/perl
$x=10;
$var="x";
$$var=30;
print $x."n";
print $$var."n";
print "$$varn";
${$var}=25;
print "${$var}"."n";
?
? ? 当对$$var进行间接访问时,Perl首先检查$var是否是引用,在这里它不是,而是字符串。于是Perl会再给该表达式一次机会:它将$var的内容当作变量标识符($x)。这样一来,最终$x的值就被修改成30了。
? ? 应当注意重要的一点是符号引用只对全局变量有效,而不能应用于那些用my标识为私有的变量。
?
符号引用对数组和散列表同样适用:
$var = "x";
@$var = (1,2,3); #将@x的值设置为右边的枚举列表
? ? ?注意$var前面的符号指示变量的存取类型:$$var等价于$x,@$var也等价于@x,这种特性非常有用。
? ? ?对于那些在Perl的早期版本中就实现过此类功能的人来说,这要比使用eval更为高效。举例说明,你要在自己的脚本程序中,处理诸如“-Ddebug_level=3”的选项,并设置$debug_level变量。下面是其中的一种实现方式:
while($arg = shift @ARGV){
if($arg =~ /-D(w+)=(w+)/){
$var_name = $1; $value = $2;
$$var_name = $value; #更为简洁的可书写为:$$1 = $2;
}
}
? ? ?从另一方面说,Perl竭尽全力使一个表达式正常工作,有时却于事无补。在前面的例子中,如果你所希望程序使用一个真正的引用,而不是字符串的话,那么你就会希望Perl能够指出这种情况而不是做任何的假定。幸运的的是,这种“急于求成”的方式可以被关闭。
? ? ?Perl有许多编译时指令和指示。strict编译指示将告诉Perl做严格的错误检查。你甚至科以指定需要进行严格检查的范围,其中之一就包括“refs”这一项:
? ? ? ? use strict 'refs'; ? ?#告诉Perl不允许符号引用
? ? ? ? $var = "x";
? ? ? ? $$var = 30;
无论何时你试图使用符号引用时均会导致运行时错误:
can't use string ("x") as a SCALAR ref while "strict refs" in use at try.pl line 3
strict指令直至程序块结束仍然有效。可以通过输入no strict 或更明确的no strict 'refs'将其关闭。
?
硬引用
1. 另一种数据类型的地址。硬引用本身是标量值。
$ptr=任何其他类型:$,@,%,&,*(typeglob),$(another ptr)
引用本身是SCALAR保存的是指针值,引用的内容是$$ptr,%$ptr,@$ptr等等。
?
2. 创建对变量的引用(指针)时没有必要命名,如果变量或者子程序没有名称则成为匿名变量或匿名子程序。中缀运算符->用于分离匿名数字和匿名散列的引用(非必须,但是增加程序可读性)。
匿名数字元素包含在放括号[]中,方括号表达式不同与下标表达式,用于给标量赋值的情况。注意“”中[]为字面量。例如
my $arrayref = ['luffy','nami','robin'];
print $arrayref->[1].”n”;
print $$arrayref[1].”n”;
print ${$arrayref}[1].”n”; #这三种形式相同
print “@{$arrayref}n” #整个数组
#匿名哈希通过{}判断,同样这里与散列下标的花括号不同,它用于将散列赋值给标量引用。
my $hashref = {Captain=”luffy”,Helmsman=”nami”,Historian=”robin”}
print “$hashref->{Captain}n”;
print keys %$hashref,“n”;
?对于各类嵌套数据结构的使用(等同于匿名数组/哈希)同样可以使用$array->[3]->[3],${$array->[3]}[3],或者$array->[3][3]; 而@{$array->[3]}表示整个嵌套数字,%{$array->[2]}表示真个嵌套哈希。内嵌套哈希的哈希可以用$hashref->{Captain}->{Luffy}或者直接$$hashref{Captain}{Luffy}。
#!/usr/bin/perl
?
my $hashref={Captain=>"luffy",Helmsman=>"nami",Historian=>"robin"};
my $arrayref = [1,$hashref]; #注意这里不能是%$hashref .
#print print $arrayref->[2]; #类型是HASH(地址);
print $arrayref->[2]->{Captain};
?
3. 匿名子程序
my $subref=sub{print @_;};
&$subref('a','b','c');
子程序传递引用:以往传递子程序时,都复制到@_数组中。如果变量太大会造成@_太大,需要放回的结果也太大。因此传递变量最有效和最简单的方式就是通过地址引用(依然通过@_传递地址,和C差不多)。
sub gifts{
?my($n,$a) = @_; #将引用本地化
?print “There are $$n gifts”;
?print “@$tn”;
?push(@$t,'abcd');
}
gifts($num,@toys); #然后abcd被实际插入到了@toys中。
?
4. 文件句柄引用
open(LOG,“/etc/passwd”) || die “error while opening”;
&readit(*LOG)
sub readit{
my($mylog)=@_;
while(<$mylog>) {
print;
}
close $mylog; #这里关闭,外面就不可以使用这个文件句柄了!
}
?
5. ref函数:用于测试引用存在,如果参数是引用则返回真。如果在printf “%s”还可以显示引用的类型。
$ptr = @arr;
printf(“$ptr is a reference to %s”,ref($ptr)) if ref($ptr);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读