2010-08-27 58 views
2

考慮這個Perl腳本:取消引用Perl中的數組鍵

use strict; 

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

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

當我試圖訪問這個元素,它給出如下錯誤:

不能使用字符串(「陣列( 0x ...)「)作爲ARRAY編號

爲什麼?

回答

3

由於哈希鍵始終是字符串化的,並且數組REFERENCE(其中的$test_ref)的字符串化值完全是:"ARRAY(0x...)"。這與可以將任意對象存儲爲密鑰的Java地圖不同。

Therfore,你的哈希將有1 KET值對,鍵爲一個字符串「"ARRAY(0x...)"

所以,當你有你的for循環,它遍歷所有的鍵(所有的人都1) ,然後將該鍵值(字符串"ARRAY(0x...)")分配給$key變量。

然後嘗試陣列解引用該字符串 - 這當然不能這樣做,因爲它不是一個數組引用 - 它僅僅是包含以前是什麼數組引用字符串表示的字符串。

如果你想擁有「24,26,55」爲3哈希鍵,你可以這樣做:

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

如果你真的想存儲在哈希鍵列表,它是可行的,但不一直(在你的整數列表的情況下,你可以,但它的速度慢,clumzy當你想給我無法想象。

# 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]; 
} 

這種方法有一定的性能損失,並可以優化了一點(例如通過記憶分割的結果)。但是,再一次,由於幾乎任何原因你可能想這樣做,巧妙的是更好的解決方案。

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; 
0

如果要訪問數組引用$test_ref,那麼你要使用數組語法(方括號)

$test_ref->[0]; 

如果你想訪問的哈希%new,然後使用哈希語法(括號)

$new{$key} 

你在做什麼是使用數組引用$test_ref作爲密鑰到散列%new - 什麼perl做的是將該數組引用轉換爲字符串使用的關鍵。這是字符串,而不是keys返回的引用。

您不能使用引用作爲鍵,然後再次獲取引用(平凡)。

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]; 
} 

幹得好。但警告更重要。