簡體   English   中英

如何將 if/else 更改為哈希函數? perl

[英]How to change if/else to hash function? perl

sub funcA{
    my ($A) = @_;  <--require 1
}
sub funcB{
    my ($A, $B) = @_;  <--require 2
}
sub funcC{
    my ($A, $B, $C) = @_;  <--require 3
}

sub funcRun{
    my ($param) = @_;
    my $other1, $other2, $other3;  <--will be assigned at ',,,,,'

    ,,,,,

    if($param eq 'a'){
        funcA, $other1;
        return;
    }elsif($param eq = 'b'){
        funcB, $other1, $other2;
        return;
    }elsif($param eq = 'c'){
        funcC, $other1, $other2, $other3;
        return;
    }
}

我想將此更改為下一個代碼

sub funcA{
    my ($A) = @_;  #<--require 1
}
sub funcB{
    my ($A, $B) = @_;  #<--require 2
}
sub funcC{
    my ($A, $B, $C) = @_;  #<--require 3
}

my $hash_ref = {
    'a' => \&funcA,
    'b' => \&funcB,
    'c' => \&funcC
}

sub funcRun{
    my ($param) = @_;
    my $other1, $other2, $other3;  #<--will be assigned at ',,,,,'

    ,,,,,

    $hash_ref->{$param}(ARGUMENTS);   #<--my problem

}

但我想不出如何制作包含可變數量參數的ARGUMENTS部分。 我認為每個函數都在funcRun代碼中定義,但是我不知道與 if/else 代碼的區別。 而且我聽說傳遞 3 個參數值並從第一個開始按順序接受參數,有人說不好

在澄清后更新。 最后一個代碼段可能正是所要求的。


參數從運行時生成的列表中決定使用哪個參數集的設計給您帶來了麻煩; 情況很復雜。 不知道實際問題我不知道還能提供什么(除了猜測)。 也許澄清這個的用途?

話雖如此,完成您想要的一種方法是在 hashref 中存儲函數的參數以及函數名稱的規范; 另一種方法是有一個單獨的結構,每個參數都有參數集。

例如

use warnings;
use strict;
use feature 'say';

my $dispatch = { 
    'a' => { name => \&funcA, lastidx => 0 },
    'b' => { name => \&funcB, lastidx => 1 },
    'c' => { name => \&funcC, lastidx => 2 } 
};

sub funcRun {
    my ($param) = @_; 
    my @args = qw(one two three);

    my $func    = $dispatch->{$param}{name};
    my $lastidx = $dispatch->{$param}{lastidx};

    $func->( @args[0..$lastidx] );
}    
sub funcA { say "@_" }
sub funcB { say "@_" }
sub funcC { say "@_" }

funcRun($_)  for qw(a b c);

印刷

one
one two
one two three

如果您確實需要從列表中按位置選擇參數,請使用數組。

但是,我建議您澄清這是什么,以便我們可以提供更簡單的設計。


根據評論中的解釋,我認為偶然的屬性實際上可能有所幫助。

如果函數funcA確實只接受第一個參數, funcB前兩個參數和funcC所有三個參數(來自運行時構建的列表),那么您可以很好地將所有參數傳遞給所有這些參數

$func->( @args );

sub funcA {
    my ($A) = @_;  # arguments other than the first are discarded
    ...
}

每個函數都接受它需要的東西,其余的參數被丟棄。

此外,如果函數以任何方式知道要采用給定參數列表中的哪一個,那么您可以再次簡單地傳遞所有參數。 然后他們可以在位置上選擇他們的論點

sub funcB {
    my ($A, undef, $B) = @_;  # if it needs first and third
    ...
}

或通過命名鍵

# Work out what arguments are for which function
my $args = { for_A => ..., for_B => ..., for_C => ... };
...
$func->( $args );

sub funcA {
    my ($args) = @_
    my $A = $args->{for_A};
    ...
}

現在參數需要存儲在哈希中。

最后也是最好的,這一切都可以在通話之前解決

my $dispatch = { a => \&funcA, b => \&funcB, c => \&funcC };

sub funcRun {
    my ($param) = @_;
    # Work out arguments for functions
    my $args = { a => ..., b => ..., c => ... };      

    $dispatch->{$param}->( $args->{$param} );
}
# subs funcA, funcB, funcC are the same   

funcRun($_)  for qw(a b c);

什么需要對您的代碼進行最少的更改(只需將參數存儲在哈希中)。

在這里,函數和調度表都不需要知道可能的參數列表,在funcRun都解決了funcRun 這避免了函數與外部代碼的糾纏。

您的問題源於這樣一個事實,即您從任意的、不相關的變量中傳遞了一組值。 因此,解決方案是將您可能想要傳遞給子程序的所有數據放在一個數據結構中,並定義一種機制來為每次調用提取正確的數據。 您已經有一個為此使用數組的解決方案,但我認為在散列中更容易理解。

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

sub funcA{
    my ($A) = @_;
    say $A;
}
sub funcB{
    my ($A, $B) = @_;
    say "$A / $B";
}
sub funcC{
    my ($A, $B, $C) = @_;
    say "$A / $B / $C";
}

my $hash_ref = {
    'a' => { func => \&funcA, args => [ qw[ other1 ] ] },
    'b' => { func => \&funcB, args => [ qw[ other1 other2 ] ] },
    'c' => { func => \&funcC, args => [ qw[ other1 other2 other3 ] ] },
};

sub funcRun{
    my ($param) = @_;

    my %args = (
        other1 => 'foo',
        other2 => 'bar',
        other3 => 'baz',
    );

    # $hash_ref->{$param}{args} is an array reference containing
    # the names of the arguments you need.
    # @{ ... } turns that array reference into an array.
    # @args{ ... } uses that array to look up those keys in the
    # %args hash (this is called a hash slice)

    $hash_ref->{$param}{func}(@args{ @{ $hash_ref->{$param}{args} } });

}

funcRun($_) for qw[a b c];

但是,老實說,將數據存儲在散列中后,將整個散列傳遞到每個子程序並讓他們確定要使用哪些數據只是一小步。 或者甚至將您的哈希值變成一個對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM