设为首页 收藏本站
查看: 1087|回复: 0

[经验分享] 《中级perl》笔记 - 2, 数组引用 (1)

[复制链接]

尚未签到

发表于 2018-8-31 07:37:47 | 显示全部楼层 |阅读模式
  正式进入主题,perl之所以受欢迎,主要有赖于两大利器: 强大的正则表达式支持 & 强大的复杂数据结构。 复杂数据结构有赖于引用这个重要的实现方式,接下来的几篇笔记将重点讨论列表(也叫数组)引用、哈希引用和函数(也叫子程序)引用。此外还有文件(目录)句柄引用和正则表达式引用,将在后续笔记简略讨论。
  引用类似于C语言的指针,它提供间接访问一个(或一组)对象的方法。直接上例子:
  my @required = qw(preserver sunscreen warter_bottle jacket);
  my @skipper   = qw(blue_shirt hat jacket preserver sunscreen);
  for my $item (@required) {
  unless (grep $item eq $_, @skipper) {    # 如果$item不在@skipper里
  print “skipper is missing $item.\n”;
  }
  }
  这段程序中, @required是Skipper先生需要带的物品,@skipper是他实际带的物品。
  for循环判断@required中,@skipper没有的元素,遇到一个打印一个。没有问题,这些代码能很好的工作,我们还可以写出以下代码来检查Gilligan和Professor有什么没带。
  my @gilligan = qw(red_shirt hat lucky_socks water_bottle);
  for my $item (@required) {
  unless (grep $item eq $_, @gilligan) {    # 如果$item不在@gilligan里
  print “gilligan is missing $item.\n”;
  }
  }
  my @professor = qw(sunscreen water_bottle silde_rule batteries radio);
  for my $item (@required) {
  unless (grep $item eq $_, @professor) {    # 如果$item不在@professor里
  print “professor is missing $item.\n”;
  }
  }
  看起来也没什么问题,不过你将发现我们重复写类似的代码,解决相同的问题。
  sub check_required_items {
  my $who = shift;
  my @required = qw(preserver sunscreen warter_bottle jacket);
  for my $item (@required) {
  unless (grep $item eq $_, @_) {
  print “$who is missing $item.\n”;
  }
  }
  }
  my @gilligan = qw(red_shirt hat lucky_socks water_bottle);
  check_required_items (‘gilligan’, @gilligan);
  my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
  my @professor = qw(sunscreen water_bottle silde_rule batteries radio);
  check_required_items(‘skipper’, @skipper);
  check_required_items(‘professor’, @professor);
  写成函数,我们省去了一部分重复代码。尽管解决了最初的问题,我们还有两个问题需要解决。
  •    每次调用函数都需要拷贝整个数组给@_,这是不小的开销,尤其当数组很大时
  •    如果我们需要改变原数组,函数调用的方式将无法做到。因为传给函数的@_参数只是原数组的一个拷贝,任何应用在@_上的改变,无法应用到原数组。
  引用可以很好地解决这两个问题。
  ** 对数组进行引用 **
  产生一个引用的方法很简单,在被引用的变量前放一个反斜杠 \就产生这个变量的引用。
  my $reference_to_skipper = \@skipper;
  引用是一个标量,它能使用在任何需要标量的场合 : 函数的标量参数、数组的元素、哈西的键或者值 。。。等等。 像普通标量那样,引用可以进行赋值操作。
  my $second_reference_to_skipper = $reference_to_skipper;
  my $third_reference_to_skipper = \@skipper;
  这三个对@skipper的引用是完全相同的东西,他们都直接指向数组@skipper的内存地址。
  ** 解析数组引用 **
  如何访问被引用的数组? 我们通过解析引用来访问数组元素。访问数组引用,类似于访问普通的数组(@后面的空格是故意加的),区别是要把引用放在大括号里:
  @  skipper
  @  { $ref_of_skipper }
  访问数组中某个元素的方法也类似:
  $ skipper [1]
  $ {$ref_of_skipper} [1]
  于是我们可以改写之前的函数,通过引用来访问数组。
  sub check_required_items {
  my $who = shift;
  my $items = shift;
  my @required = qw(preserver sunscreen water_bottle jacket);
  for my $item (@required) {
  unless (grep $item eq $_, @{$items}) {
  print “$who is missing $item.\n”;
  }
  }
  }
  我们可以重复调用这个函数,检查人们是否遗失了什么。
  my @gilligan = qw(red_shirt hat lucky_socks water_bottle);
  check_required_items (‘gilligan’, \@gilligan);
  my @skipper = qw(blue_shirt hat jacket preserver sunscreen);
  check_required_items(‘skipper’, \@skipper);
  my @professor = qw(sunscreen water_bottle silde_rule batteries radio);
  check_required_items(‘professor’, \@professor);
  函数定义部分,我们只是把@_替换成数组引用;调用函数时,我们把第二参数换成待检查数组的引用。这样做解决了之前的第一个问题,不需要再拷贝原数组给@_,而是函数直接访问目标数组。后面我们将看到引用是如何解决第二个问题的。
  我们还可以把函数中的两个shift语句去掉,不过这样维护起来更困难了。
  sub check_required_items {
  my @required = qw(preserver sunscreen water_bottle jacket);
  for my $item (@required) {
  unless (grep $item eq $_, @{$_[1]}) {    #$_[1]是传给函数的@_第二个参数
  print “$_[0] is missing $item.\n”;    #$_[0]是传给函数的第一个参数
  }
  }
  }


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-559072-1-1.html 上篇帖子: perl监控硬盘空间的方法 下篇帖子: 安装软件提示缺少perl模块的解决方法
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表