为什么我会在Perl中返回哈希或哈希引用?

use*_*033 10 perl hash reference

实现以下目标的最有效方法是什么?(我知道他们完成了同样的事情,但大多数人如何在三者之间做到这一点,为什么?)

档案a.pl

my %hash = build_hash();
# Do stuff with hash using $hash{$key}
sub build_hash
{
    # Build some hash
    my %hash = ();
    my @k = qw(hi bi no th xc ul 8e r);
    for ( @k )
    {
        $hash{$k} = 1;
    }

    # Does this return a copy of the hash??
    return %hash;
}
Run Code Online (Sandbox Code Playgroud)

文件b.pl

my $hashref = build_hash();
# Do stuff with hash using $hashref->{$key}
sub build_hash
{
    # Build some hash
    my %hash = ();
    my @k = qw(hi bi no th xc ul 8e r);
    for ( @k )
    {
        $hash{$k} = 1;
    }

    # Just return a reference (smaller than making a copy?)
    return \%hash;
}
Run Code Online (Sandbox Code Playgroud)

文件c.pl

my %hash = %{build_hash()};
# Do stuff with hash using $hash{$key}
# It is better, because now we don't have to dereference our hashref each time using ->?

sub build_hash
{
    # Build some hash
    my %hash = ();
    my @k = qw(hi bi no th xc ul 8e r);
    for ( @k )
    {
        $hash{$k} = 1;
    }

    return \%hash;
}
Run Code Online (Sandbox Code Playgroud)

Sch*_*ern 22

我更喜欢返回散列引用有两个原因.一,它使用的内存少一点,因为没有副本.第二,如果你只需要一个哈希值,它就可以让你这样做.

my $value = build_hash()->{$key};
Run Code Online (Sandbox Code Playgroud)

学习爱哈希引用,一旦开始使用对象,你将会看到它们.

  • 你想要一些鸡蛋吗?(隐式哈希引用:) (6认同)

Eri*_*rom 9

为什么不回归?上下文是Perl中一个非常强大的功能,允许您的功能"做你的意思".通常,决定哪个是更好的返回值取决于调用代码计划如何使用该值,这正是Perl具有内置的原因wantarray.

sub build_hash {
    my %hash;
    @hash{@keys} = (1) x @keys;
    wantarray ? %hash : \%hash
}

my %hash = build_hash;  # list context, a list of (key => value) pairs
my $href = build_hash;  # scalar context, a hash reference
Run Code Online (Sandbox Code Playgroud)

  • @Eric它不是不理解上下文.它是否期望build_hash()在列表上下文中返回不同的东西.不要相信用户研究并永远记住每个功能的文档.它的复杂性在于:'my($ foo)`和`my $ foo`相当容易随意交换.还有`function(build_hash())`.哎呀.很容易错过微妙的错误.最后,重新调整哈希没有返回列表的效用.必须将哈希插入变量才有用.返回列表可以隐式使用,LISP样式.所以我质疑价值. (3认同)
  • `my($ href)= build_hash(); #whoops.对于没有足够的胜利有点太多的帮助. (2认同)
  • @Schwern =>如果在Perl工作的人无法识别左值是否在分配上强加了列表上下文,他们就不会走得太远.那些了解它们的人应该帮助其他人正确使用这些功能,而不是将这些功能隐藏起来. (2认同)

Dav*_*ris 8

我将返回引用以保存将散列扁平化为标量列表的处理时间,构建新散列和(可能)垃圾收集子例程中的本地散列.


Eth*_*her 5

您正在寻找的是哈希切片:

# assigns the value 1 to every element of the hash

my %hash;                                   # declare an empty hash
my @list = qw(hi bi no th xc ul 8e r);      # declare the keys as a list
@hash{@list} =                              # for every key listed in @list,
                (1) x @list;                # ...assign to it the corresponding value in this list
                                            # which is (1, 1, 1, 1, 1...)  (@list in scalar context
                                            #   gives the number of elements in the list)
Run Code Online (Sandbox Code Playgroud)

x操作者在被描述的perldoc perlop得到.

有关数据结构和参考资料的教程,请参阅perldoc perldscperldoc perlreftut(初学者和专家都必须阅读).perldoc perldata中提到了哈希切片本身.

关于从函数返回哈希,通常你应该返回哈希本身,而不是引用.你可以使用一个引用,如果哈希是巨大的,内存或时间是一个问题,但这不应该是你的第一个担心 - 使代码工作.

函数的返回值总是列表(返回标量本质上是一个元素的列表).散列是Perl中的列表:您可以互换地将一个分配给另一个(假设列表具有偶数个元素,并且没有键冲突会导致某些值在转换期间丢失):

use strict; use warnings;
use Data::Dumper;

function foo
{
    return qw(key1 value1 key2 value2);
}

my @list = foo();
my %hash = foo();

print Dumper(\@list);
print Dumper(\%hash);
Run Code Online (Sandbox Code Playgroud)

得到:

$VAR1 = [
          'key1',
          'value1',
          'key2',
          'value2'
        ];

$VAR1 = {
          'key2' => 'value2',
          'key1' => 'value1'
        };
Run Code Online (Sandbox Code Playgroud)

PS.我强烈建议你编写像上面这样的小样本程序来玩数据结构并看看会发生什么.你可以通过实验学到很多东西!