0

这是我目前的想法,但我不知道如何调度/执行它

我的 $key;
我的@arraydata;

我的 %commandfunc{
"ab 1", \&func1(\@arraydata),
"ab 2", \&func2(\@arraydata,
"ab 3", \&func3(\@arraydata)
};

foreach $k(键 %commandfunc){
  if($something =~ /$k/){ #if $something 匹配一个键字符串
        $key=$k;
        #这里处理arraydata;
    }

}
#调度??
我的 $command = $commandfunc{$key}->(\@arraydata);

请更正我的代码..非常感谢

4

3 回答 3

6

哈希使用常规括号 ( ( )) 进行初始化,而不是花括号(用于哈希引用。)并且您使用列表分配初始化哈希。所以第一部分应该是:

my %commandfunc = ( 
    "ab 1" => \&func1,
    "ab 2" => \&func2,
    "ab 3" => \&func3
);

操作符比使用逗号更漂亮一些,=>并且如果需要的话,它还具有在左侧引用裸词的额外好处。

我不确定您要在循环中匹配什么($_从哪里来?)但是您可以执行以下操作:

foreach my $k (keys %commandfunc) {
    if( $something =~ /$k/) {
        my $result = $commandfunc{$k}->( \@arraydata );
    }
}
于 2009-11-23T05:41:04.613 回答
5

\&func1是一个子例程引用,但\&func1(\@arraydata)它是对 &func1 调用返回值的引用。试试吧:"ab 1" => \&func1, .... @arraydata 的传递在您的调度代码中是正确的。

请注意,这/$k/将使元字符像 . 或 * 在正则表达式中具有特殊效果;如果你不想那样做,那就做吧/\Q$k/。或者你可能想要只是eq $k

于 2009-11-23T05:36:40.323 回答
4

您并不清楚是否@arraydata预先定义,以及此代码执行的频率。您的尝试的直接翻译将产生:

my %commandfunc = (
    "ab 1" => sub { func1(@arraydata) },
    "ab 2" => sub { func2(@arraydata) },
    "ab 3" => sub { func3(@arraydata) },
};

if (my ($match) = grep { $_ eq $key } keys %commandfunc)
{
    my $result = &{$commandfunc{$match}};
}

然而,这不是很有效 -%commandfunc哈希是用匿名子例程闭包定义的,当我们可以只将 coderefs 存储到原始 subs 而不绑定任何参数时,然后传入一个数组:

my %commandfunc = (
    "ab 1" => \&func1,
    "ab 2" => \&func2,
    "ab 3" => \&func3,
};

并这样称呼它:

my $result = $commandfunc{$match}->(@array);
于 2009-11-23T06:07:36.447 回答