Perl 在与函数调用相同的行上获取哈希键/值

Perl 在与函数调用相同的行上获取哈希键/值,perl,Perl,下面是重现问题的代码: sub hello { return (h => 1, n => 1); } print join ", ", values hello(); 我得到一个错误: arg 1 to值的类型必须为哈希 (非子程序条目)在第4行, 近“;”执行-由于 避免编译错误 我知道我可以在两行上中断通话和打印: sub hello { return (h => 1, n => 1); } my %hash = hello(); print join ", ",

下面是重现问题的代码:

sub hello { return (h => 1, n => 1); }
print join ", ", values hello();
我得到一个错误:

arg 1 to值的类型必须为哈希 (非子程序条目)在第4行, 近“;”执行-由于 避免编译错误

我知道我可以在两行上中断通话和打印:

sub hello { return (h => 1, n => 1); }
my %hash = hello();
print join ", ", values %hash;

但我不想那样做。是否有某种方法可以在一行中实现这一点,这样我就不必一直创建临时变量?

我认为这是不可能的,因为Perl的类型不够强,无法知道子例程返回什么

就Perl而言,所有子例程只返回列表(或单个标量)。列表可以应用某些操作(索引、切片等),但不需要数组变量(如
push
pop
shift
)或散列变量(包括
删除
存在)


散列赋值将列表作为参数(函数返回),并创建一个关联散列,每个奇数元素作为下一个偶数元素的键。只有在这个赋值之后,它才能在Perl语法中被称为哈希,因此只有在这个赋值之后,它才能在
values
函数中使用。

您可以使用哈希引用:

sub hello { return {h => 1, n => 1}; }
print join ", ", values %{hello()};
否则,Perl可能会在标量或列表上下文中解释子例程的返回值,但没有在哈希上下文中返回值的概念


更新:这同样有效

sub hello { return (h => 1, n => 1); }
print join ", ", values %{{hello()}};
内部
{}
hello()
的输出从列表转换为哈希引用。 外部
%{}
取消对散列的引用


(在真正的程序中,
%{{}}
算是一个吗?

我看不出有什么用处,但是是的,这是可能的

print join ", ", values %{{hello()}};

说明:
hello()
是一个列表
{hello()}
是一个哈希引用
%{{hello()}
是一个散列。

您可以做的另一件事是使用切换变量

sub hello { return (h => 1, n => 1); }
my $toggle = 1;
print join ", ", grep { $toggle = !$toggle; } hello();
你可以做的另一件事是使用

使用列表::成对qw;
打印join“,”,mapp{$b}hello();

我一直在寻找一些东西来处理一个“流”中的名称-值对列表,甚至我自己的,但后来我在CPAN上发现了这个

比我的答案晚+1,但你花时间写了一个解释。它在实际程序中一直都很有用。如果您从API返回一个哈希值,而您所需要的只是键或值。@tster:这是不同的。当然,
%{sub\u returning\u hash()}
是有用的。但问题是子函数返回plist(即包含键和值序列的列表),这在Perl中并不常见。返回哈希的函数与向调用函数返回数组的函数没有什么不同。另外,返回散列的函数在perl中可能不常见,但我处理了很多。
use List::Pairwise qw<mapp>;
print join ", ", mapp { $b } hello();