-1

在 Perl 中,如果我有:

no strict;
@ARY = (58, 90);

要对数组的一个元素进行操作,比如说第二个,我会写(可能作为更大表达式的一部分):

$ARY[1]  # The most common way found in Perldoc's idioms.

虽然,出于某种原因,这些也有效:

@ARY[1]
@{ARY[1]}

导致所有在同一个对象中:

print (\$ARY[1]);
print (\@ARY[1]);
print (\@{ARY[1]});

输出:

SCALAR(0x9dbcdc)
SCALAR(0x9dbcdc)
SCALAR(0x9dbcdc)

启用这种结构的语法规则是什么?使用这些结构中的每一个,或者混合所有这些结构,设计出可靠的程序代码能走多远?这些表达的互换性如何?(总是在非严格的上下文中说话)。

关于证明我如何进入这个问题的理由,我同意“使用严格”作为一种更好的做法,但我仍然对建立非严格表达式的一些知识感兴趣。

在试图为自己的这种不安找到一些帮助时,我想到了:

  • “不严格”的概念;不要抱怨未声明的变量和怪异的语法。
  • 前缀取消引用具有比子索引 [] 更高的优先级(perldsc §“优先级警告”)。
  • 关于何时使用 @ 而不是 $ 的说明(perldata § "Slices")。
  • Perl 的运算符 (perlop) 中缺少“[]”(数组下标/切片)描述,这让我认为它不是运算符……(但它必须是别的东西。但是,什么?)。

对于我所学到的,这些提示都没有让我更好地理解我的问题。

提前致谢。

4

4 回答 4

4

来自 perlfaq4 的报价:

$array[1]和 和有什么不一样@array[1]

不同之处在于 sigil,即数组名称前面的特殊字符。印记的$意思是“恰好一个项目”,而@印记的意思是“零个或多个项目”。为$您提供一个标量,而 为@您提供一个列表。

请看:$array[1] 和@array[1] 有什么区别?

于 2014-09-08T22:08:44.733 回答
2

@ARY[1]确实是一个切片,实际上一个切片只有一个成员。不同之处在于它创建了一个列表上下文:

@ar1[0] = qw( a b c );    # List context.
$ar2[0] = qw( a b c );    # Scalar context, the last value is returned.
print "<@ar1> <@ar2>\n";

输出:

<a> <c>

除了使用strict,也打开warnings。您将收到以下警告:

Scalar value @ar1[0] better written as $ar1[0]

在 perlop 中,您可以读到“Perl 的前缀取消引用运算符类型为:$、@、% 和 &。” 标准语法是SIGIL { ... },但在简单的情况下,可以省略大括号。

请参阅在使用“严格引用”时可以将字符串用作 HASH 引用吗?no strict refs在严格的情况下进行一些有趣的仿真。

于 2014-09-08T22:07:10.883 回答
1

扩展choroba 的答案,以检查特定的上下文,您可以使用wantarray

sub context { return wantarray ? "LIST" : "SCALAR" }

print $ary1[0] = context(), "\n";
print @ary1[0] = context(), "\n";

输出:

SCALAR
LIST
于 2014-09-08T22:39:53.063 回答
1

no strict;除了隐藏你做的错误之外,你所做的任何事情都不需要

@ARY = (58, 90);

当你应该做的时候

my @ARY = (58, 90);

以下返回数组的单个元素。由于EXPRis 返回单个索引,因此在标量上下文中对其进行评估。

$array[EXPR]

例如

my @array = qw( a b c d );
my $index = 2;
my $ele = $array[$index];   # my $ele = 'c';

以下返回由 标识的元素LIST。由于LISTis 返回 0 个或更多元素,因此必须在列表上下文中对其进行评估。

@array[LIST]

例如

my @array = qw( a b c d );
my @indexes ( 1, 2 );
my @slice = $array[@indexes];   # my @slice = qw( b c );

\( $ARY[$index]   )  # Returns a ref to the element returned by $ARY[$index]
\( @ARY[@indexes] )  # Returns refs to each element returned by @ARY[@indexes]

${foo}       # Weird way of writing $foo. Useful in literals, e.g. "${foo}bar"
@{foo}       # Weird way of writing @foo. Useful in literals, e.g. "@{foo}bar"
${foo}[...]  # Weird way of writing $foo[...].

大多数人甚至不知道您可以在字符串文字之外使用这些。

于 2014-09-09T04:13:32.513 回答