在 Perl 中,我正在学习如何取消引用“子例程引用”。但我似乎无法使用子例程引用作为哈希“键”。
在以下示例代码中,
- 我可以创建对子例程 ($subref) 的引用,然后取消引用它以运行子例程 (&$subref)
- 我可以使用引用作为哈希“值”,然后轻松取消引用
- 但我不知道如何使用引用作为哈希“键”。当我从散列中取出 key 时,Perl 将该 key 解释为字符串值(而不是引用) - 我现在 understand (感谢这个网站!)。所以我尝试了 Hash::MultiKey,但这似乎将它变成了数组引用。我想将其视为子例程/代码引用,假设这在某种程度上是可能的?
还有其他想法吗?
use strict;
#use diagnostics;
use Hash::MultiKey;
my $subref = \&hello;
#1:
&$subref('bob','sue'); #okay
#2:
my %hash;
$hash{'sayhi'}=$subref;
&{$hash{'sayhi'}}('bob','sue'); #okay
#3:
my %hash2;
tie %hash2, 'Hash::MultiKey';
$hash2{$subref}=1;
foreach my $key (keys %hash2) {
print "Ref type is: ". ref($key)."\n";
&{$key}('bob','sue'); # Not okay
}
sub hello {
my $name=shift;
my $name2=shift;
print "hello $name and $name2\n";
}
这是返回的内容:
hello bob and sue
hello bob and sue
Ref type is: ARRAY
Not a CODE reference at d:\temp\test.pl line 21.
最佳答案
这是正确的,普通的哈希键只是一个字符串。非字符串的内容被强制为其字符串表示形式。
my $coderef = sub { my ($name, $name2) = @_; say "hello $name and $name2"; };
my %hash2 = ( $coderef => 1, );
print keys %hash2; # 'CODE(0x8d2280)'
Tie ing 是修改该行为的常用方法,但是 Hash::MultiKey对你没有帮助,它有不同的目的:正如名称所示,你可能有多个键,但同样只有简单的字符串:
use Hash::MultiKey qw();
tie my %hash2, 'Hash::MultiKey';
$hash2{ [$coderef] } = 1;
foreach my $key (keys %hash2) {
say 'Ref of the key is: ' . ref($key);
say 'Ref of the list elements produced by array-dereferencing the key are:';
say ref($_) for @{ $key }; # no output, i.e. simple strings
say 'List elements produced by array-dereferencing the key are:';
say $_ for @{ $key }; # 'CODE(0x8d27f0)'
}
相反,请使用Tie::RefHash 。 (代码评论:更喜欢使用带有 ->
箭头的语法来取消对 coderef 的引用。)
use 5.010;
use strict;
use warnings FATAL => 'all';
use Tie::RefHash qw();
my $coderef = sub {
my ($name, $name2) = @_;
say "hello $name and $name2";
};
$coderef->(qw(bob sue));
my %hash = (sayhi => $coderef);
$hash{sayhi}->(qw(bob sue));
tie my %hash2, 'Tie::RefHash';
%hash2 = ($coderef => 1);
foreach my $key (keys %hash2) {
say 'Ref of the key is: ' . ref($key); # 'CODE'
$key->(qw(bob sue));
}
关于perl - 如何使用 'subroutine reference' 作为哈希键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10795386/