您不能将 Perl $_ 分配给 foreach 语句中的散列

You can't assign Perl $_ to a hash in a foreach statement

我已经尝试了所有我能想到的方法(加上大量的随机实验)来将 foreach 语句中的 $_ 分配给哈希。我知道您可以在 foreach 行之后分配它,但我有一个非常特殊的代码限制,不允许我这样做。

#!/usr/bin/perl -s

use strict;
use Data::Dumper;

my @x = qw(a c e g);
my $var = {'a'=>"z", 'b'=>"y", 'c'=>"x", 'd'=>"w", 'e'=>"v", 'f'=>"u", 'g'=>"t", 'h'=>"s"};
my $y = "e";
foreach $var->{$y} (@x){
    print "$y = $var->{$y}\n";
    $y = $var->{$y};
}

我认为正在发生的事情是 perl 编译器无法在它正在寻找要将 $_ 分配给 $VAR 的位置处理“{”和“}”字符。当我 运行 代码时,我不仅收到有关 foreach 行的错误,而且还收到有关没有语法错误的打印行的语法错误。

syntax error at ./foreach2var.pl line 9, near "$var->"
syntax error at ./foreach2var.pl line 12, near "}"
Execution of ./foreach2var.pl aborted due to compilation errors.

有什么方法可以将 foreach 语句中的 $_ 直接分配给哈希引用,而不是在下一行用 $var->{$y} = $_; 分配它?

我正在寻找以下输出

e = a
a = c
c = e
e = g

此外,我知道以下方法有效,但同样,我有一个特定的代码限制,这意味着我必须能够处理 foreach 语句

#!/usr/bin/perl -s

use strict;
use Data::Dumper;

my @x = qw(a c e g);
my $var = {'a'=>"z", 'b'=>"y", 'c'=>"x", 'd'=>"w", 'e'=>"v", 'f'=>"u", 'g'=>"t", 'h'=>"s"};
my $y = "e";
while($var->{$y} = shift @x){
    print "$y = $var->{$y}\n";
    $y = $var->{$y};
}

来自Foreach Loops in perlsyn

The foreach loop iterates over a normal list value and sets the scalar variable VAR to be each element of the list in turn.

因此,它需要一个 变量 并且您想要分配给的解除引用的 computed-on-the-fly 值甚至不是左值,更不用说变量了。

这个“变量”要求有多严格?该段的其余部分是

If the variable is preceded with the keyword my, then it is lexically scoped, and is therefore visible only within the loop. Otherwise, the variable is implicitly local to the loop and regains its former value upon exiting the loop. If the variable was previously declared with my, it uses that variable instead of the global one, but it's still localized to the loop. This implicit localization occurs only in a foreach loop.

所以我们确实需要一个变量。虽然这个要求纯粹是语法上的。

我不确定你到底需要做什么以及你的限制是什么,但是

for (@x) { 
    $var->{$y} = $_;
    ...
}

确实如问题中所观察到的那样按需要分配。

将其指定为主题词,for $v (@ary) { },确实有额外的 属性 在循环中本地化 $v,正如上面从文档中引用的那样,但你似乎没有需要那个部分。


一个 可以 定位复杂结构的一部分。一个 command-line 程序

perl -Mstrict -wE'
    my $hr = { k => 2 };  say $hr->{k}; 
    SAVE: { local $hr->{k} = 7; say $hr->{k} }; 
    say $hr->{k}'

打印行 272

没有。根据文档,它必须是一个变量。

它真的没有任何意义,因为变量的值在循环结束时恢复。

$_ = "abc";
say;

for (qw( def ghi )) {
   say;
}

say;

输出:

abc
def
ghi
abc

您可以从以下各项获得所需的输出:

my $prev = "e";
while ( @x ) {
   my $this = shift( @x );
   say "$prev = $this";
   $prev = $this;
}
my $prev = "e";
for my $this ( @x ) {
   say "$prev = $this";
   $prev = $this;
}
my $this = "e";
while ( @x ) {
   ( my $prev, $this ) = ( $this, shift( @x ) );
   say "$prev = $this";
}
unshift @x, "e";
for my $i ( 1 .. $#x ) {
   say "$x[ $i - 1 ] = $x[ $i ]";
}