Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么要在Perl中返回哈希或哈希引用?_Perl_Hash_Reference - Fatal编程技术网

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

为什么要在Perl中返回哈希或哈希引用?,perl,hash,reference,Perl,Hash,Reference,实现以下目标的最有效方法是什么?(我知道他们完成了同样的事情,但大多数人会如何在这三者之间做到这一点,为什么?) 文件a.pl 文件b.pl 文件c.pl 我将返回引用,以节省将散列整平为标量列表、构建新散列以及(可能)在子例程中对本地散列进行垃圾收集的处理时间 您要查找的是哈希切片: 有关x运算符的说明,请参见 有关数据结构和参考的教程,请参见和(初学者和专家都必须阅读)。中提到了散列切片本身 关于从函数返回散列,通常应该返回散列本身,而不是引用。如果散列非常大,并且内存或时间是一个问题,那么

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

文件a.pl 文件b.pl 文件c.pl
我将返回引用,以节省将散列整平为标量列表、构建新散列以及(可能)在子例程中对本地散列进行垃圾收集的处理时间

您要查找的是哈希切片:

有关
x
运算符的说明,请参见

有关数据结构和参考的教程,请参见和(初学者和专家都必须阅读)。中提到了散列切片本身

关于从函数返回散列,通常应该返回散列本身,而不是引用。如果散列非常大,并且内存或时间是一个问题,那么可以使用引用,但这不应该是您首先担心的问题——让代码正常工作是非常重要的

函数的返回值总是列表(其中返回的标量本质上是一个元素的列表)。散列在Perl中是列表:您可以交替地将一个分配给另一个(假设列表中的元素数为偶数,并且不存在会导致某些值在转换过程中丢失的键冲突):

给出:

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

$VAR1 = {
          'key2' => 'value2',
          'key1' => 'value1'
        };

另外,我强烈建议编写像上面这样的小样本程序来处理数据结构,看看会发生什么。你可以通过实验学到很多

注意:
a.pl
返回包含偶数个元素的列表,而不是散列。然后,当您将这样一个列表分配给散列变量时,将使用偶数索引处的元素作为键,奇数索引处的元素作为值来构建散列。[编辑:我总是这样看待这件事,但是
sub{…%hash}
的行为实际上与
sub{…@list}
有点不同]

出于同样的原因,按照您描述的方式构建散列非常简单:

my %hash = map { $_ => 1 } qw(hi bi no th xc ul 8e r);
我个人的经验法则是避免引用,除非我真的需要它们(例如嵌套结构,或者当您真的需要传递对同一事物的引用时)

编辑:(我不能再点击“添加评论”链接了?!在这里使用鼠标键…) 我考虑了一下,我认为传递散列引用毕竟可能更好,因为我们使用散列的方式。但上面的段落仍然适用于数组引用


感谢您的评论,Schwern和Ether。

a.pl
c.pl
需要获取散列的副本(函数内部的散列标记为可用内存)<另一方面,code>b.pl,只构建一次散列,并且只需要很少的额外内存来返回一个可以操作的引用。因此,无论在空间还是时间上,
b.pl
更有可能是这三种格式中最有效的一种。第一,由于没有拷贝,它使用的内存少了一点。第二,如果您只需要一块散列,它可以让您这样做

my $value = build_hash()->{$key};

学会喜欢散列引用,一旦你开始使用对象,你会看到很多散列引用。

我会违背粒度和其他人的说法,说我更喜欢将数据作为散列返回(好吧,作为一个大小均匀的列表,可能会被解释为散列)。我工作的环境中,我们倾向于执行以下代码段之类的操作,当您不必每隔一行取消引用时,组合、排序、切片和骰子就容易得多。(很高兴知道有人不能破坏您的hashref,因为您通过值传递了整个内容。编辑:,除非您在hash值中引用了其他对象/哈希/数组,否则您无论如何都会遇到麻烦)

这近似于我的代码可能做的事情:基于各种配置策略对象(其中一些对象天生就知道,再加上一些额外的家伙)为对象构建配置,然后过滤掉其中一些不相关的对象

(是的,我们有很好的工具,如
hashgrep
hashmap
lkeys
,它们可以对哈希进行有用的操作。$a和$b分别设置为列表中每个项目的键和值)。(是的,我们有可以在这一级别编程的人员。招聘令人讨厌,但我们有高质量的产品。)


如果您不想做类似函数式编程的事情,或者您需要更高的性能(您分析过吗?),那么当然可以使用hashrefs。

为什么不同时返回两者?上下文是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
关于从 函数,通常应该返回 散列本身,而不是引用。你 如果哈希为,则可以使用引用 巨大的记忆或时间是一个问题, 但这不应该是你首先担心的 --让代码正常工作是非常困难的

我不同意你的看法。有一段时间,我采取了这个立场,但很快发现自己陷入了一个地狱,必须记住哪个
sub
s返回哈希值,哪个返回hashrefs,这是让代码正常工作的一个相当严重的障碍。标准化始终返回hash/array或始终返回hashref/arrayref是很重要的,除非您想经常被自己绊倒

关于标准化,我认为使用参考文献有几个优点:

  • 返回哈希或数组时,实际返回的是一个列表,其中包含原始哈希/数组的展开副本。就像将散列/数组参数传递给
    子文件
    ,这样做的缺点是您只能继续发送
    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);
    
    $VAR1 = [
              'key1',
              'value1',
              'key2',
              'value2'
            ];
    
    $VAR1 = {
              'key2' => 'value2',
              'key1' => 'value1'
            };
    
    my %hash = map { $_ => 1 } qw(hi bi no th xc ul 8e r);
    
    my $value = build_hash()->{$key};
    
    my %filtered_config_slice = 
       hashgrep { $a !~ /^apparent_/ && defined $b } (
       map { $_->build_config_slice(%some_params, some_other => 'param') } 
       ($self->partial_config_strategies, $other_config_strategy)
    );
    
    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