我怎样才能将Perl的每个与列表一起使用?

How can I use Perl's each with a list?

提问人:con 提问时间:11/14/2023 最后编辑:tooliccon 更新时间:11/14/2023 访问量:142

问:

我正在尝试:

#!/usr/bin/env perl

use 5.038;
use warnings FATAL => 'all';
use autodie ':all';
use Devel::Confess 'color';

while (my ($i, $t) = each('a','b','c')) {
    say "$i, $t";
}

但我收到一个错误:

Experimental each on scalar is now forbidden

('a','b','c')是标量吗?

我真的很喜欢 Perl 对数组的处理,因为我不必声明迭代器变量。each

我也试过了

while (my ($i, $t) = each(('a','b','c'))) {

while (my ($i, $t) = each(qw('a','b','c'))) {

但得到同样的错误。

while (my ($i, $t) = each(@{ ('a','b','c') }) {

但上面给出了一个错误:我从如何解决 perl 中的“标量实验值现在被禁止”问题中得到Useless use of a constant ("a") in void context

我怎样才能说服Perl的('a','b','c')是一个数组?each

Perl的

评论

0赞 zdim 11/14/2023
不错的尝试。但是:1)是,不是。请参见 qw。2)如果你这样做,那么它取消了对数组引用的引用--所以里面必须是一个数组引用;所以(其中创建一个匿名数组,一个引用)。但是,这也不起作用,因为它的原型需要一个实际的变量 ()qw(a b c)qw('a','b','c')@{...}@{[ qw(a b c) ]}[...]each@
1赞 con 11/14/2023
@TLP我的意思是一个额外的变量,它不会像我上面那样是局部的
2赞 Dada 11/14/2023
@TLP我认为他们的意思是他们试图通过这样做来避免,这是完全合理的。“因为我不必声明迭代器变量”可能应该是“因为我不必在外部范围内声明迭代器变量”。my $i = 0; for my $t (@arr) { ...; $i++ }for (my ($i, $t) = each @arr) { ... }
1赞 Dada 11/14/2023
@TLP我不同意。同时拥有索引和元素可能很有用,并且正是为此而设计的。此外,OP 并不建议使用全局变量:他们说“它不会是局部的”,但我很确定他们的意思是“它会在外部范围内”,而不是“它会是全局的”。each ARRAY
2赞 Dada 11/15/2023
@TLP我认为对这个答案投赞成票的 8733 人(显示了 Python 等价物)会不同意。另外,为什么一般来说你不需要额外的迭代器,当然在某些情况下,它很好。each

答:

2赞 toolic 11/14/2023 #1

('a','b','c')不是数组;这是一个列表。请参阅每个

如果将列表分配给数组变量,它将起作用:

my @array = ('a','b','c');
while (my ($i, $t) = each(@array)) {
    say "$i, $t";
}

输出:

0, a
1, b
2, c
4赞 zdim 11/14/2023 #2

我怎样才能说服Perl的每个('a','b','c')是一个数组?

你不能,因为只是一个字符串文字(标量)的列表。它不是一个数组变量。('a','b','c')

每个文档都很清楚

每个哈希

每个 ARRAY
...

所以它需要一个变量,要么是哈希,要么是数组。


还有一个错误出现的问题

但我收到一个错误:

Experimental each on scalar is now forbidden

('a','b','c')是标量吗?

首先,我收到的此类代码的完整错误消息

perl -wE'while( my ($i, $t) = each(qw(a b c)) ) { say "$i, $t" }'

很有启发性

Experimental each on scalar is now forbidden at -e line 1.
Type of arg 1 to each must be hash or array (not list) at -e line 1, near "qw(a b c)) "
Execution of -e aborted due to compilation errors.

该函数已原型化each

perl -wE'say prototype "CORE::each"'  #-->  \[%@]

所以它需要一个项目,它需要是一个哈希或数组变量。通过向它传递一个列表,我们有一个在编译时捕获的不匹配,并且应该是致命的。所以游戏就这样结束了。

然而,我相信这是一个额外的礼貌,我们也得到了关于“在标量上进行实验”的信息。

问题是,如果原型中的这种不匹配通过(不是致命的),那么列表将是一个要计算的表达式,它产生三个标量或一个标量(通过逗号运算符,前两个项目被丢弃,表达式返回,或者,如果优先级相反,则返回其余部分), 取决于上下文。'a', 'b', 'c''c''a'

在任何一种情况下,标量都用于 ,过去允许然后警告不要,然后完全禁止,因此我们(仍然)收到额外的消息。each

评论

0赞 zdim 11/14/2023
该函数是原型的,打印(在 v5.32 上),因此它需要变量。也许有可能(?)在那里构建并给它一个数组,但这样做将是一个真正的暴行,远远超过声明数组的不优雅。perl -wE'say prototype "CORE::each"'\[%@]
0赞 choroba 11/14/2023
我很好奇这是怎么回事。我没能做到这一点:它不适用于取消引用的匿名数组,因为它每次都会重新创建它,因此它不会遍历第一个元素。
0赞 zdim 11/14/2023
@choroba是的,这里也一样;这就是为什么所有的对冲(可能,?不知道如何创建一个数组给出变量,内联。当我尝试“传递”它时,我动态所做的任何操作(arrayref、block)都会被评估到列表中。(我什至犯了罪,留下了徒劳的罪......eachdoeval
0赞 zdim 11/14/2023
@ikegami 谢谢,我添加了一个胖脚注(在看到您的消息之前,我没有收到通知?怎么知道它会是标量上下文?原型已经有一个列表,所以我认为错误消息的“实验标量”部分是“假设”。\[%@]
0赞 ikegami 11/15/2023
关于“怎么知道它会是标量上下文?”,算子实际上并不使用原型。其实不然.它接受了一段时间的引用,这是一个标量。因此,那里的任何东西都会被评估为标量。但背景有点没有意义。所以不提是件好事。\[%@]