在Perl中取消引用数组键

时间:2010-08-27 15:38:16

标签: perl

考虑一下这个Perl脚本:

use strict;

my %new;
my $test_ref = [24, 26, 55];
$new{$test_ref} = 10;

foreach my $key (keys %new){
    print $key->[0];
}

当我尝试访问此元素时,会出现如下错误:

  

不能使用字符串(“ARRAY(0x ...)”)作为ARRAY参考

为什么?

4 个答案:

答案 0 :(得分:3)

因为哈希键总是被字符串化,并且数组REFERENCE($test_ref是)的字符串化值恰好是:"ARRAY(0x...)"。这与可以将任意对象存储为密钥的Java映射不同。

因此,你的哈希值有1个ket-value对,键是一个字符串“"ARRAY(0x...)"

因此,当你有for循环时,它会循环遍历所有密钥(全部为1),然后将密钥值(字符串"ARRAY(0x...)")分配给$key变量

然后尝试对该字符串进行数组取消引用 - 当然,由于它不是数组引用,因此无法完成 - 它只是一个包含所用数组引用的字符串表示形式的字符串是。

如果你想将“24,26,55”作为3个哈希键,你可以这样做:

my %new = map { $_ => 10 } @$test_ref;

如果你真的想把一个列表存储在一个哈希键中,它是可行的但并不总是(在你的整数列表的情况下,你可以,但它很慢,很笨拙,我无法想象你什么时候希望。

# Trivial example:
my $test_ref = [24, 26, 55];
$new{ join(",",@$test_ref) } = 10;
foreach my $key (keys %new){
    my @list = split(/,/,$key);
    print $list[0];
}

这种方法有一些性能损失,可以稍微优化(例如通过记忆拆分结果)。但同样,由于您可能想要这样做的原因,可能有更好的解决方案。

答案 1 :(得分:2)

哈希键通常是字符串化的,因此它们无法充当引用。

核心模块Tie::RefHash提供此功能:

use strict;
use warnings;
use Tie::RefHash;

tie my %new, 'Tie::RefHash';
my $test_ref = [24, 26, 55];
$new{$test_ref} = 10;

foreach my $key (keys %new){
    print $key->[0];
}

使用严格的好工作。但警告更为重要。

答案 2 :(得分:0)

我猜测(我可能错了)您想要将24,26和55分配为%new的键。

如果您想这样做,以下是您的目标:

use strict;

my %new;
my $test_ref = [24, 26, 55];

@new{@$test_ref} = (10) x @$test_ref;

print "$new{$_}\n" foreach keys %new;

答案 3 :(得分:0)

如果要访问数组引用$test_ref,则需要使用数组语法(方括号)

$test_ref->[0];

如果要访问哈希%new,请使用哈希语法(大括号)

$new{$key}

您正在做的是使用数组引用$test_ref作为哈希%new的键 - perl所做的是将该数组引用转换为要在键处使用的字符串。它是字符串,而不是keys返回的引用。

您不能将引用用作键,然后再次(稍微)获取引用。