在声明Perl哈希时,我想知道是否可以使用在声明中先前分配的值。
我想一次性完成相同的操作:
my %H = (something => generateString());
$H{foo} = $H{something} . "/FOO",
$H{bar} = $H{something} . "/BAR",
我可以想象这样的事情:
my %H = (
something => generateString(),
foo => $_{something} . "/FOO",
bar => $_{something} . "/BAR",
);
编辑:要明确,我不关心$H{something}
的实际引用(即稍后更改$H{something}
不应影响$H{foo}
) 。我只想把它的值放到字符串连接中。
答案 0 :(得分:5)
您似乎认为
中有两个赋值运算符%H = ( a=>1, b=>$H{a} );
没有。请记住以上内容与
相同%H = ( 'a', 1, 'b', $H{a} );
有一个赋值运算符,在执行赋值之前,您需要知道将要赋值的是什么。
我所说的是%H = ( a=>1, b=>$H{a} );
的真正问题不在于范围之一;真正的问题是,%H
[1] 时,$H{a}
没有分配任何内容。因此,$_{a}
比$H{a}
更有意义。
解决方案很简单:
my $something = generateString();
my %H = (
something => $something,
foo => "$something/FOO",
bar => "$something/BAR",
);
%H
甚至尚未创建!答案 1 :(得分:2)
my %H = (something => generateString());
%H = (%H,
foo => $H{something} ."/FOO",
bar => $H{something} ."/BAR",
);
看起来很合理,但如果你想以任何代价一次拍摄,
use strict;
use warnings;
%{ $_->{hash} } = (
something => $_->{thing},
foo => "$_->{thing}/FOO",
bar => "$_->{thing}/BAR",
)
for {hash => \my %H, thing => generateString()};
可以翻译成更详细的版本,
my %H;
local $_ = {hash => \%H, thing => generateString()};
%{ $_->{hash} } = (
something => $_->{thing},
foo => "$_->{thing}/FOO",
bar => "$_->{thing}/BAR",
);
答案 2 :(得分:2)
正如池上所说,只有一项任务操作;在评估整个右侧之后执行它。
几种选择:
my %H = map {;
'something' => $_,
'foo' => "$_/FOO",
'bar' => "$_/BAR",
} generateString();
和
use Memoize;
memoize('generateString');
my %H = (
'something' => scalar(generateString()),
'foo' => generateString() . '/FOO',
'bar' => generateString() . '/BAR',
);
(标量需要,否则,memoize会对列表和标量上下文进行单独调用。)
答案 3 :(得分:1)
另一种方法是将定义作为分配的一部分:
my %H = (
something => ( local our $str=generateString() ),
foo => qq{$str/FOO},
bar => qq{$str/BAR}
);
有两件事需要考虑:
local our
代替my
我觉得在哈希定义之外定义一个变量(如池上的回答所示)是出于很多原因的最佳方法,但我意识到这也不是被问到的问题。这个问题的答案是在创建哈希之前不能引用哈希,在创建过程中哈希不会在构造函数中公开。