访问引用数组的元素

3

我是Perl的新手。我写了一段代码来访问数组元素并将其打印到控制台:

use strict;
use warnings;

my @array1 = ('20020701  00000', 'Sending Mail in Perl', 'Philip Yuson');
my @array2 = ('20020601', 'Manipulating Dates in Perl', 'Philip Yuson');
my @array3 = ('20020501', 'GUI Application for CVS', 'Philip Yuson');
my @main = (\@array1, \@array2, \@array3);

my $a = $main[0];
print @$a;
print @$a . "pdf";

第一次打印:

20020701  00000使用Perl发送邮件Philip Yuson

但是为什么第二次打印输出是这个呢?

3pdf 

我需要得到如下的输出结果

20020701  00000使用Perl发送邮件Philip Yusonpdf

我不知道为什么它会给出 3pdf,我很着急,请帮忙解决。非常感谢。


你想要的输出看起来非常奇怪。你确定这就是你想要的吗?也许你可以解释一下为什么它看起来那样。 - brian d foy
5个回答

14

3 是数组中元素的数量。点号 . 强制将数组转换为标量上下文,然后您可以获得元素数量而不是数组内容。您可以使用

print "@$a pdf";

或者

print @$a , "pdf";

根据您想要的输出类型而定。


12

数组是 Perl 中根据“上下文”而表现不同的部分之一,而“上下文”是 Perl 编程中非常重要的概念。考虑以下内容:

my @fruits = qw/apples pears bananas/;
my $items = @fruits;

在第二行中,您正在为标量赋值(⇒这里我们有一些上下文),但是在右侧您有一个数组。我们说这里使用了数组在标量上下文中,并且在标量上下文中,数组的值是其项数。

现在来看看您的问题:当您仅打印数组时,没有太多神奇的东西。但是当您尝试使用 . 运算符将字符串附加到数组时,您正在使用标量上下文中的数组。这意味着数组的值评估为其项数( 3 ),然后您将 pdf 附加到其中。

清楚吗?您应该在Google上搜索“Perl上下文”等内容,这将使Perl编程更容易。


提供一个或两个已知的有用链接,而不是一条搜索方向,会更有用。 - naught101

6
这是一个关于上下文的问题。在Perl中,一个值的数据类型只是它被评估的一部分;另一半是该值所用的上下文。
正如您所知,有三种内置数据类型:标量、数组和哈希。这些数据类型之间还存在一定程度的隐式转换。
还有两个主要的上下文:列表和标量。数组和哈希在列表上下文中都可以工作而无需转换;标量值在标量上下文中不需要改变。
运算符的行为取决于它运行的上下文。如果运算符需要特定的上下文,并且Perl能够将值隐式转换为与该上下文匹配的内容,则会进行转换。在将数组和关联数组转换为整数的情况下,得到的是数组的“基数”,即它包含的元素数量。
在您上面的示例中,@$a评估为数据类型为数组。然而,这个故事的另一半是运算符.运行的上下文。阅读perldoc perlop,它说:

二进制.连接两个字符串。

好吧,字符串是标量值,因此我们需要将数组@$a转换为在标量上下文中有效的值,并在这样做时获得数组的基数。 @$a包含3个元素,因此这将评估为标量值3,然后将其转换为字符串,以便.运算符可以发挥其魔力。
希望这有些意义。

2
不存在所谓的“哈希上下文” - 或者数组上下文(尽管有误命名的wantarray函数)。存在标量上下文和列表上下文,以及一些次要的细节,例如布尔上下文(标量的子集)。 - friedo
1
你有一些错误。上下文是voidlistscalarBooleanstringnumeric上下文是标量上下文的类型。此外,在标量上下文中的哈希返回已使用和分配的桶的数量--而不是成员的数量,请参阅perldata获取更多信息。另外,当你提到“数组上下文”时,这让我想到你正在混淆列表和数组,它们之间有很大的区别:http://perldoc.perl.org/perlfaq4.html#What-is-the-difference-between-a-list-and-an-array%3f - daotoad
你们两个都是对的。我已经编辑了我的回答,希望能够消除一些不准确之处。 - Ed Carrel

4

print join("", @$a) . "pdf" 在标量上下文中计算数组,从而输出数组中的元素个数,这就是为什么会得到3的原因。

你可能需要像这样做:

print @$a, "pdf";

逗号运算符代替点运算符可以强制将其转换为列表上下文。

3
我感觉你真正想要的是:

我有一个感觉,你真正想要的是:

print "@$a.pdf", "\n";

That is:

my @array1 = ('20020701  00000', 'Sending Mail in Perl', 'Philip Yuson');
my @array2 = ('20020601', 'Manipulating Dates in Perl', 'Philip Yuson');
my @array3 = ('20020501', 'GUI Application for CVS', 'Philip Yuson');
my @main = (\@array1, \@array2, \@array3);

for my $x ( @main ) {
    print "@$x.pdf", "\n";
}

输出:

20020701  00000 在 Perl 中发送电子邮件 Philip Yuson.pdf
20020601 操作Perl中的日期 Philip Yuson.pdf
20020501 CVS 的 GUI 应用程序 Philip Yuson.pdf

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