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

[经验分享] [Perl]引用传递和值传递

[复制链接]

尚未签到

发表于 2015-12-28 14:04:07 | 显示全部楼层 |阅读模式
[Perl]引用传递和值传递
版权声明:可以任意转载,但转载时必须标明原作者charlee、原始链接http://tech.idv2.com/2008/10/15/perl-ref/以及本声明。





    这个题目似乎有些不太合适,因为这并不是我们常说的引用传递和值传递。但是我想提醒大家这一点,否则很容易犯错误。
  问题:map语句的代码段中使用的 $_,是列表中的值本身,还是将列表中的值复制到 $_ 中?
  例如,下面这段程序的运行结果是什么呢?

#!/usr/bin/perl
$,=',', $\="\n";
$a = [1,2,3];
print map { ++$_; } @$a;     # (A)
print @$a;                   # (B)
  C程序员们通常会认为map会将@$a中的每个值复制到 $_ 中,加一后返回(这里我特地用了 ++$_ 使得它返回加一之后的值),因此(A)行输出 2,3,4 ,而(B)行输出 1,2,3 。实则不然。运行结果为

2,3,4
2,3,4
  可见,并非@$a中的元素复制到$_中,而是$_本身就是@$a中的元素。而map的目的就是要改变操作数的值。下面这个例子可以很清楚地看到这一点。

map { ++$_ } (1,2,3);    # 运行时出错,++$_ 不能改变常量
  类似地,grep的结果也是数组本身,返回值就是由操作数中的符合条件的元素本身组成的列表。如上例:

map { ++$_; } grep { $_ > 1 } @$a;  # 运行后 $a 为 [1,3,4]
  如果实在不想让map改变操作数的值,可以将操作数转成引用之后再强制转成数组:

map { ++$_; } @{[ @$a ]};    # 运行后 $a 为 [1,2,3]
  当然,上面例子中 ++ 操作符很明显会改变操作数的值,因此意识到上面的问题并不困难。不过如果是 s/// 运算符,可能就不那么明显了。
  类似的情况还有函数调用时的 @_ ,它代表调用函数时的实际参数本身,而不是实际参数的拷贝。对@_进行修改,会直接影响到实参(就像C语言里面的传指针一样)。
  一般我们在定义函数时都这么写:

sub foo {
my $arg1 = shift;
}
  参数多时可能会这么写:

sub foo {
my ($arg1, $arg2, $arg3) = @_;
}
  这样写之后,@_的值就被赋给了$arg1、$arg2等变量,以后对$arg1、$arg2的修改不会影响到实际参数。但如果想修改实际参数,就要这样做:

my $arg1 = \$_[0];
$$arg1 = 'Hello!';        # 调用函数时的第一个实参会变成 Hello!

运维网声明 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-157542-1-1.html 上篇帖子: Perl 学习手札总目录 下篇帖子: [转]perl中my和our的区别
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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