【问题标题】:How do I use Perl keys() from a function return value?如何从函数返回值中使用 Perl 键()?
【发布时间】:2013-03-06 01:30:48
【问题描述】:

我知道 Perl keys() 函数,并希望在我拥有的哈希上使用它,但看不出有任何理由为其设置变量。让我在代码中解释两种方式:

正常:

my %hash = ReturnsHash();
foreach (keys(%hash)) {
    ...code...
}

我想要的方式:

foreach (keys(ReturnsHash())) {
    ...code...
}

使用第二种方法我收到此错误消息(Type of arg 1 to keys must be hash or array (not subroutine entry))第二种方法可能吗?如果有怎么办?

【问题讨论】:

  • 这很可能与您编写它的方式完全相同。您是否尝试过这种方法?如果是,请解释它是如何失败的。
  • 我添加了错误,我也在使用 5.012 和警告
  • @cdhowie:这是 5.14+ 的实验性功能

标签: perl hash


【解决方案1】:

与它的名字相反,ReturnsHash 不返回哈希值。 sub 不可能返回散列。 Subs 只能返回标量列表。如果你这样做了

sub ReturnsHash {
   my %hash = ( a => 1, b => 2 );
   return %hash;
}

你在做

return 'a', 1, 'b', 2;

既然你做不到

keys('a', 1, 'b', 2)

你做不到

keys(ReturnsHash())

现在,您可以做的是返回对哈希的引用

sub ReturnsHashRef {
   my %hash = ( a => 1, b => 2 );
   return \%hash;
}

又名

sub ReturnsHashRef {
   return { a => 1, b => 2 };
}

在这种情况下你可以这样做

keys(%{ ReturnsHashRef() })

【讨论】:

  • 我在阅读您的帖子之前偶然发现了keys(%{ ReturnsHashRef() }),感谢您的解释和正确答案!
  • 另一种方法是从返回的列表中创建一个哈希引用并将其取消引用作为keys 函数的输入,例如%{ {ReturnsHash()} }
  • @Birei,是的,但如果可能的话,这是你想要避免的事情。我想不出return %hash; 什么时候有意义。 (好吧,也许如果该函数打算在标量上下文中调用。)
  • 即使抛开返回散列是否有意义,如果你将散列展平为列表,返回列表,然后将其复制到匿名散列中,Perl 肯定会做更多的工作以便可以再次取消引用。
  • @DavidO,就像我说的,如果可能的话,你想避免的事情。 :)
【解决方案2】:

没有“返回哈希”的函数。如果你有

sub foo {
    ...
    return %hash;
}

my %h = foo();

那么 foo 不会“返回哈希”;它返回%hash 中键和值的列表。该列表用于创建新的哈希%h。正如 Joel 所说,如果您将 reference 返回到哈希,那么 keys %$href 是有意义的,但您不能在列表上运行 keys 而不将其分配给哈希首先。

【讨论】:

    【解决方案3】:

    我想你已经明白了。从您的函数中,只需返回一个哈希引用,然后在您的 foreach 块内,密钥将存储在 $_ 变量中。这是一个例子:

    sub ReturnsHash {
    
        return { key1 => 'value1', key2 => 'value2' };
    }
    
    foreach (keys(%{ReturnsHash()})) {
        print 'key:=' . $_ . "\n";
    }
    

    【讨论】:

    • @Eric Fossum:您使用的是哪个 Perl 版本? Perl pre-5.14 可能需要您取消引用哈希引用:foreach ( keys %{ ReturnsHashref() } ) {.....
    • 即使在 5.14+ 中也是良好做法。
    【解决方案4】:

    既然可以返回hash reference,为什么还要返回整个笨重的hash

    我总是会返回hash reference

    sub return_hash() {
       ## Code 
       return \%hash;
    }
    

    并以

    的形式接收它
    foreach (keys(%{ return_hash() })) {
     ## code
    }
    

    还有一件事,编写所有函数名称以small case letter 开头并通过_ 分隔的单词始终被视为良好的编码约定。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多