慕村225694

Perl 可以通过函数元型在编译期进行有限的参数类型检验。如果你声明sub mypush (+@)那么 mypush() 对参数的处理就同内置的 push() 完全一样了。函数声明必须要在编译相应函数调用之前告知编译器(编译器在编译函数调用时会对相应函数用 prototype来查询它的元型来进行参数检验,并决定怎样编译此函数调用)。元型只在不用 & 调用函数的时候起作用。就是说在语法上如果你想像内置函数一样调用,它就表现的像内置函数一样。如果想用过时的风格通过 & 调用,那么编译器就无视函数声明。另外元型在函数引用如 \&foo 和间接调用如 &{$subref} 和 $subref->() 时也不起作用。方法调用也不受元型影响,因为实际调用的函数无法在编译期决定,它是由继承关系决定的。因为这个特性最初的目的是使你可以像内置函数那样调用自己的函数,所以下面就给出等价于内置函数调用方式的函数元型。声明为 调用方式sub mylink ($$) mylink $old, $newsub myvec ($$$) myvec $var, $offset, 1sub myindex ($$;$) myindex &getstring, "substr"sub mysyswrite ($$$;$) mysyswrite $buf, 0, length($buf) - $off, $offsub myreverse (@) myreverse $a, $b, $csub myjoin ($@) myjoin ':', $a, $b, $csub mypop (+) mypop @arraysub mysplice (+$$@) mysplice @array, 0, 2, @pushmesub mykeys (+) mykeys %{$hashref}sub myopen (*;$) myopen HANDLE, $namesub mypipe (**) mypipe READHANDLE, WRITEHANDLEsub mygrep (&@) mygrep { /foo/ } $a, $b, $csub myrand (;$) myrand 42sub mytime () mytime任何 \ 跟着的函数元型中的字符代表着实际的参数必须由相应字符开头(参数前可跟my our local 声明),只有 $ 例外,它可以接收并不以 $ 开头的 hash 和数组的元素,比如 my_function()->[0]。传给 @_ 的参数将会是相应实际参数的引用,即对它加 \。你可以用 \[] 来表示多个可用的类型。比如:sub myref (\[$@%&*])上面的函数声明允许像下面这样调用 myref() 这个函数myref $varmyref @arraymyref %hashmyref &submyref *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 的元素个数,和分割的元素个数。

linux上perl怎么传输参数,如何在perl子函数中传递参数?相关推荐

  1. linux中probe函数中传递的参数来源(上)

    点击打开链接 上一篇中,我们追踪了probe函数在何时调用,知道了满足什么条件会调用probe函数,但probe函数中传递的参数我们并不知道在何时定义,到底是谁定义的,反正不是我们在驱动中定义的(当然 ...

  2. 算法训练 - P1101 ——有一份提货单,其数据项目有:商品名(MC)、单价(DJ)、数量(SL)。定义一个结构体prut,其成员是上面的三项数据。在主函数中定义一个prut类型的结构体数组,输入每

    问题描述 有一份提货单,其数据项目有:商品名(MC).单价(DJ).数量(SL).定义一个结构体prut,其成员是上面的三项数据.在主函数中定义一个prut类型的结构体数组,输入每个元素的值,计算并输 ...

  3. linux上开发应用程序_如何在Linux上安装软件应用程序

    linux上开发应用程序 如何在Linux上安装应用程序? 与许多操作系统一样,该问题不仅有一个答案. 应用程序可以来自许多来源-几乎无法计数-每个开发团队都可以以自己认为最佳的方式交付软件. 知道如 ...

  4. 在红帽Linux上安装samba服务,如何在linux上安装配置samba服务器

    如何在linux上安装配置samba服务器 更新时间:2019-10-29 22:40 最满意答案 1.首先需要登入安装了Linux系统的计算机,安装Samba.Fedora发行版一般使用yum工具安 ...

  5. linux上查看网络限制,如何在Linux上限制网络带宽

    您是否曾经与多个设备共享网络带宽?如果您曾经处于一个应用程序占用了所有流量的位置,那么您是系统管理员还是Linux用户,您将需要发现如何控制应用程序的上载和下载速度,以确保您的带宽并不完全被单个应用程 ...

  6. Linux终端文件夹管理员,如何在Ubuntu 18.04中以管理员权限打开文件和文件夹

    本文向你介绍在Ubuntu 18.04中以管理员权限打开文件和文件夹. 与 Windows 中的资源管理器一样,在 Ubuntu 系统的 Nautilus 文件管理器中,您也可以查看到系统中的所有文件 ...

  7. 如何在HTTP POST请求中发送参数?

    本文翻译自:How are parameters sent in an HTTP POST request? In an HTTP GET request, parameters are sent a ...

  8. 如何在JQuery $ .each函数中编辑全局变量?

    好的,这样的标题可能无法很好地解释我的问题. 希望这是有道理的. 这也是我第一个使用jQuery的应用程序,因此,如果我做一些愚蠢的事情,请原谅我. 我有以下功能: function getRando ...

  9. 如何在matlab sfunction 函数中调用自己写的函数?

    自己编写了一个s函数,有几个参数引用了自己写的几个函数,在脚本中可以正确运行,但在写成s函数,进行 simulink 仿真的时候,已知提示"too many input auguments& ...

最新文章

  1. python数据处理实例-Python----数据预处理代码实例
  2. python笔记-列表和元组
  3. 《大话设计模式》Python 版代码实现
  4. Linux命令(4):开挂机重启
  5. python几行代码识别验证码_Python有多强?文字识别(验证码识别)只需三行代码!...
  6. QT.pro工程文件中判断宏定义是否存在
  7. 【Unity】unity3d客户端网络框架
  8. web服务器ngix基础
  9. openvino系列 13. 使用 OpenVINO 多模型级联使用:车辆检测与识别示例
  10. linux qt触摸屏配置,QT触摸屏的实现
  11. 警告怎么去除Reports empty tag body. The validation works in XML / JSP / JSPX / HTML/ XHTML file types
  12. 抖音矩阵系统源码搭建,抖音矩阵系统开发原理,抖音矩阵系统搭建
  13. Qt实现触摸屏校准界面
  14. forEach 终止循环
  15. Flink实时数仓--ClickHouse数据可视化接口实现、Sugar 数据大屏
  16. CentOS下LVM的使用
  17. Ubuntu下载常用软件和使用Caffe时的常见问题
  18. Linux WIFI 驱动
  19. 线性表中的尾插法单链表的学习
  20. 天涯明月刀霸王枪服务器维护,天涯明月刀6月16日服务器维护更新内容公告

热门文章

  1. 【BZOJ 1597】 [Usaco2008 Mar]土地购买 (斜率优化)
  2. 经验之谈:10位顶级PHP大师的开发原则
  3. POJ 2485 Highways (prim最小生成树)
  4. sharepoint 2007页面显示真实的错误信息
  5. Silverlight 全屏显示
  6. Luogu P3975 [TJOI2015]弦论
  7. 2018-1-27:内存的划分
  8. 《计算机科学概论》—第3章3.3节文本表示法
  9. SpringJDBC解析3-回调函数(update为例)
  10. javascript 15位和18位身份证的正则表达式及其验证