如何在Perl中引用分割表达式?

17
我想在Perl中创建对通过split获取的数组的引用。 我考虑的代码是:
my $test = \split( /,/, 'a,b,c,d,e');

foreach $k (@$test) {
   print "k is $k\n";
}

但是会抱怨:c:\ temp \ test.pl第3行不是ARRAY引用。我尝试了几种其他替代方法,但都没有成功。

3个回答

35

背景说明:

split,像其他函数一样,返回一个列表。你不能对一个列表取引用。但是,如果你将引用运算符应用到一个列表上,它会被应用到它所有的成员。例如:

use Data::Dumper;

my @x = \('a' .. 'c');

print Dumper \@x

输出结果:

$VAR1 = [
          \'a',
          \'b',
          \'c'
        ];

因此,当你写my $test = \split( /,/, 'a,b,c,d,e');时,你会得到一个指向返回列表的最后一个元素的引用(参见例如“列表”和“数组”的区别是什么?)。您的情况类似于:

尽管右侧看起来像是一个列表,但实际上Perl看到的是一堆由逗号分隔的标量:

my $scalar = ( 'dog', 'cat', 'bird' );  # $scalar gets bird
由于您正在分配给一个标量变量,因此右侧处于标量语境。在标量语境中,逗号运算符(是的,它是一种运算符!)评估其左操作数,丢弃结果,并评估其右操作数并返回结果。实际上,这个类似于列表的东西将其最右边的值分配给了$scalar。许多人会犯这个错误,因为他们选择了一个类似于列表的东西,其最后一个元素也是他们期望的计数:
my $scalar = ( 1, 2, 3 );  # $scalar gets 3, accidentally
在您的情况下,RHS(右手边)返回的是对split返回列表中元素的引用列表,该列表的最后一个元素最终存储在$test中。您需要先从这些返回值构建一个数组并取得它的引用。您可以通过形成匿名数组并将其引用存储在$test中来将其变为单个语句。
my $test = [ split( /,/, 'a,b,c,d,e') ];

这就是我为什么喜欢 Stack Overflow!非常感谢您详尽、耐心和非常清晰的解释。现在完全清楚了,今天我学到了很多。谢谢! - dr jerry

20

在方括号中包含split命令以创建一个匿名引用。

my $test = [ split( /,/, 'a,b,c,d,e') ];

谢谢,我在我的Perl书中被反斜杠的例子误导了一些。 - dr jerry
1
这样做和将划分结果存储在变量@splitResult中,然后使用$arrayRef = \@splitResult引用该变量有同样的效率吗?还是数组会被初始化两次?一次在划分期间,另一次在初始化匿名数组引用时。 - Despertar

0

给它命名在语义上有所不同,因为对命名变量的更改会改变引用的内容,而每个匿名数组都是唯一的。我通过在循环中这样做来发现这一点。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接