Perl 标量上下文中如何得到列表

本文由帖子《perl标量上下文和列表上下文的1个问题》整理而来,说明了为何在某些情况下,标量上下文中使用”列表“没法得到本身元素的个数,和如何取得你所期望的结果。

1. “列表”在标量上下文中并不是1定会得到元素的个数

也许你觉得这个标题有1些奇怪:依照Perl 上下文的定义,列表在标量上下文中会得到列表元素的个数。单纯通过这个逻辑来看,下面的语句似乎会让$scalar 被赋值3:

$scalar = qw/a b c/;

但是Perl 总会在1些不起眼的地方强行给你1个大欣喜,如果你打印$scalar 的值,你会发现你得到的是"c"而非"3"。


2. 为何可以被称为真谛的上下文规则“失效”了

似乎对非Perl 程序员,说明这个问题要简单许多。为了理解为何上下文规则在这里“失效”了,我们必须抛开“列表在标量上下文中会得到列表元素的个数”这样1个看似是真谛的结论,而从语言本身再去看待这个问题。

依然是这条语句

$scalar = qw/a b c/;

Perl 中所有的qw 运算符都会被展开成列表情势,所以这条语句和下1条完全等价:

$scalar = ('a', 'b', 'c',);

固然这两条语句都会把$scalar 赋值为"c"。

下面让我们忘掉上下文规则,通过Perl 的眼睛去看看在这里Perl 看到了甚么:

1. 赋值号以后是1个左括号,而括号是1种优先级束缚,括号中的表达式被优先计算。

2. 括号中是由1串被逗号隔开的表达式,所以天经地义的是1个逗号表达式。

3. 逗号表达式的值是最后1个表达式的值,最后1个表达式是’c’,它的值也是’c’。

4. 所以全部逗号表达式的值是’c’

5. 将’c’ 赋值给$scalar。

这就是Perl 的眼睛所看到的东西,也是为何$scalar 会被赋值为’c’ 的缘由。

所以给你1条语句:

$scalar = scalar qw/a b c/;

如果你开始以Perl 的眼睛来看代码,你就会明白上面的语句和下1条语句等价:

$scalar = scalar 'c';

天经地义,你得到的依然是"c" 而非"3"。

3. 我们所熟知的Perl 真谛难道是谬论吗?

对Perl 程序员有1个信条:上下文规则即是绝对的真谛。由于这条规则就是Perl 的思考方式,正确性无可置疑。

固然,这条真谛在上面的语句中依然有效。

之所以会带来上下文规则失效了的错觉,是由于我们常常习惯以自己的眼睛而非Perl 的眼睛去看代码。刚才在解释$scalar 为何会得到’c’ 的时候,我们也间接地表达了1个事实,在语句

$scalar = qw/a b c/;
$scalar = ('a', 'b', 'c',);
$scalar = scalar qw/a b c/;

乃至是语句

$scalar = scalar ('a', 'b', 'c',);

中,都不存在任何列表

上下文规则不可能出错,列表在标量上下文中返回的永久都是列表中元素的个数,但是在我们前面写的所有语句中,的确不曾出现过任何1个列表。


4. 如何在标量上下文中使用列表

如果想这样做,方法就是显式的告知Perl 赋值号右侧是1个列表而非逗号表达式:

$scalar = @{ ['a', 'b', 'c',] };

其中赋值号右侧的方括号告知Perl 这是1个匿名列表的援用,而@{$aref} 则是列表的解援用情势,所以赋值号右侧我们得到了1个列表"(‘a’, ‘b’, ‘c’)", 而非逗号表达式"(‘a’, ‘b’, ‘c’)"。而根据上下文规则,列表在标量上下文中会得到列表元素的个数。天经地义$scalar 被赋值为3。

回过头来,让我们看另外一条语句:

@array = qw/a b c/;

根据qw 展开规则,这条语句和下面1条语句等价:

@array = ('a', 'b', 'c',);

赋值号左侧是1个列表,所以这条语句是1个列表上下文,Perl 会在列表上下文中将赋值号的右侧理解为1个列表"(‘a’, ‘b’, ‘c’,)" 而非逗号表达式"(‘a’, ‘b’, ‘c’,)"。这个不难理解――在列表上下文中天经地义Perl 会期望1个列表,而在标量上下文中天经地义Perl 会期望1个标量。所以相同的表达式

('a', 'b', 'c',)

会在标量上下文中被当作1个逗号表达式,而在列表上下文中被认为是1个列表。Perl 只是在寻觅它期望得到的东西。

5. 去理解Perl 而非让Perl 理解你

这件事是2 年前自己学Perl 的时候也非常不解的1件事,在查阅了很多资料后才理解为何我的代码会这样运作。我觉得这也是1个Perl 程序员所必须经历的1个转变:

Perl 和其他语言有些不同――写Perl 的时候需要用Perl 的思惟去思考,你需要理解Perl,而非让Perl 去理解你的代码。

波比源码 – 精品源码模版分享 | www.bobi11.com
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!

波比源码 » Perl 标量上下文中如何得到列表

发表评论

Hi, 如果你对这款模板有疑问,可以跟我联系哦!

联系站长
赞助VIP 享更多特权,建议使用 QQ 登录
喜欢我嘛?喜欢就按“ctrl+D”收藏我吧!♡