0

これが私の現在の考えですが、ディスパッチ/実行する方法がわかりません

私の $key;
私の@arraydata;

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

foreach $k (keys %commandfunc){
  if($something =~ /$k/){ #if $something がキー文字列と一致する場合
        $key= $k;
        #ここで配列データを処理中;
    }

}
#派遣??
私の $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ハッシュは無名サブルーチンクロージャで定義されています。代わりに、引数をバインドせずに元のサブルーチンにコードリファレンスを格納し、後で配列に渡すことができます。

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

次のように呼び出します。

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