2010-07-30 35 views
1

在这里得到哈希键/值是重现该问题的代码:在同一行函数调用

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

我得到的错误:

Type of arg 1 to values must be hash (not subroutine entry) at - line 4, near ");" Execution of - aborted due to compilation errors.

我知道我可以打破通话并在两行上打印:

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

但我不想这样做。有没有办法在一行中做到这一点,以便我不必一直创建临时变量?

回答

8

我没有看到一个真正的程序的实用性,但是是的,这是可能的。

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

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

+0

它在实际的程序中一直很有用。如果您从API获取哈希值,并且您只需要键或值。 – tster 2010-07-30 20:26:50

+0

@tster:这是不同的。当然'%{sub_returning_hash()}'很有用。但是问题是关于一个返回plist的子集(即包含键和值的连续列表),这在Perl中并不常见。 – Gilles 2010-07-30 20:51:57

+0

返回散列的函数与将数组返回给调用函数的函数没有区别。另外,返回哈希的函数可能在你的perl中不常见,但我处理了很多。 – tster 2010-07-31 12:03:57

-1

我不认为这是可能的,因为Perl没有足够强的类型来知道哪些子程序返回。

就Perl而言,所有的子程序都只返回LISTs(或一个SCALAR)。 LIST可以对它们应用某些操作(索引,切片等),但不需要ARRAY变量(如push,pop,shift)或HASH变量(包括keys,,)。

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

8

您可以使用哈希引用:

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

但除此之外,没有。 Perl可以在标量或列表上下文中解释子例程的返回值,但是没有在哈希上下文中返回值的概念。


更新:这也适用

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

{}hello()从列表中的输出转换成一个散列引用。 外部%{}解除引用散列。

(是否%{{}}}数为pseudo-operator?)

+0

+1比我的回答晚了,但你花时间写了一个解释。 – MvanGeest 2010-07-30 19:58:46

+1

我会使用一些间距'%{{hello()}}'读得好一点。 – Axeman 2010-07-30 20:21:30

2

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

sub hello { return (h => 1, n => 1); } 
my $toggle = 1; 
print join ", ", grep { $toggle = !$toggle; } hello(); 

你可以做的另一件事是使用​​

use List::Pairwise qw<mapp>; 
print join ", ", mapp { $b } hello(); 

我一直在寻找的东西来处理“流”的名字 - 值对的列表,甚至推出自己的,但随后我在CPAN上找到了这个。

相关问题