Perl - 将参数传递给子例程作为哈希键 - 值对问题

kk.*_*kk. 5 perl hash subroutine

我必须将两个引用作为参数传递给子例程(buildRanges)作为哈希键 - 值对,如下所示

例:

@array = (“0A0”, “005”, “001”, “004”, “0BC”, “004”, “002”, “001”);
@ranges = ();
$numRanges = buildRanges(VALUES => \@array, REF_RANGES=>\@ranges);
Run Code Online (Sandbox Code Playgroud)

我的问题是
1.上面的子程序调用的语法是否正确?
2. VALUES和REF_RANGES是什么?

坦率地说,我无法理解子程序调用,但我被告知只能使用该调用.

谢谢.

KK

Yaa*_*lch 28

说明

是.这种语法对于Perl来说是正确和惯用的.让我们剖析函数调用的所有部分 - 很可能你已经知道部分解释了.

准备:输入数据

@array = (“0A0”, “005”, “001”, “004”, “0BC”, “004”, “002”, “001”);
@ranges = ();
# \@array and \@ranges are now normal scalar references.
Run Code Online (Sandbox Code Playgroud)

我希望你理解引用数组的概念.如果没有,请阅读perlreftut或perllol.实际上,这不会影响您询问的调用语法.顺便说一下,你可能也写过:

$array_ref=[“0A0”, “005”, “001”, “004”, “0BC”, “004”, “002”, “001”];
$range_ref=[];

$numRanges = buildRanges(VALUES => $array_ref, REF_RANGES=> $range_ref);
Run Code Online (Sandbox Code Playgroud)

函数调用

在Perl中,箭头操作符=>就像一个普通的逗号一样工作(我们稍后会讨论一个小的副作用).以下调用完全相同:

$numRanges = buildRanges(VALUES => $array_ref, REF_RANGES => $range_ref);
$numRanges = buildRanges("VALUES", $array_ref, "REF_RANGES", $range_ref);
Run Code Online (Sandbox Code Playgroud)

因此,您只需使用四个参数调用函数buildRanges:两个常量字符串和两个数组引用.您注意到VALUES一词已更改为常量字符串"VALUE"; 同样适用于REF_RANGES这个词.这是一个特殊规则:在箭头=>和大括号{}之前,普通标识符会以静默方式转换为字符串.我们在下面再看一遍.但是像$ a => $ b这样的其他表达式保持原样,没有对字符串进行静默转换.

您可能会问为什么Perl会这样做?这是语法糖:=>运算符没有做任何你不能轻易做到的事情.但是对于有经验的perl程序员来说,格式KEY => $ value看起来比"KEY",$ value更清晰.

功能定义

函数buildRanges的定义可能如下所示(我们在解释中使用它):

sub buidRanges { my(%info)=@_; 
  my $values    = $info{VALUES};
  my $ref_ranges= $info{REF_RANGES};
  my $special_feature = $info{SPECIAL_FEATURE}; # explained below
  if($special_feature) { ... return special_result; }
  ... process $values and $ref_ranges ... return $numRanges.
}
Run Code Online (Sandbox Code Playgroud)

使用输入数据,以下四行中的每一行都具有相同的效果:

my(%info)=@_;                                          # the actual code
my(%info)=(VALUES => \@array, REF_RANGES=> \@ranges ); # what this does

my %info; $info{"VALUES"}=\@array; $info{"REF_RANGES"}=\@ranges; 
my %info; $info{ VALUES }=\@array; $info{ REF_RANGES }=\@ranges; 
Run Code Online (Sandbox Code Playgroud)

基本上,输入数据被转换为允许访问每个参数的哈希.函数调用中的常量字符串成为散列键.

选择一条你理解的行并将其与其他行进行比较:它们做同样的事情.请查看perldsc以获取更多解释.

请注意,在我们的示例中,@ _是输入参数的数组

@_ = ( VALUES => \@array, REF_RANGES=> \@ranges); 
@_ = ("VALUES",  \@array,"REF_RANGES", \@ranges);  # without syntactic sugar
Run Code Online (Sandbox Code Playgroud)

你可能已经注意到$ info {VALUES}相当于$ info {"VALUES"} - 再次,这是语法糖,如上所述.

在我们的假设实现中,我们将输入数据从哈希中拉出来:

 my $values     = $info{VALUES};       # i.e:  my $value      = \@array;
 my $ref_ranges = $info{REF_RANGES};   # i.e:  my $ref_renges = \@ranges;
Run Code Online (Sandbox Code Playgroud)

现在,我们的函数实现可以处理输入数据.

为什么我们这样做并不简单?---命名参数

到目前为止,我们可以更简单地实现类似的效果:

$numRanges = buildRanges($array_ref, $range_ref);  # simpler function call

sub buidRanges { my($values, $ref_ranges)=@_; 
  ... process $values and $ref_ranges ... return $numRanges.
}
Run Code Online (Sandbox Code Playgroud)

这很可能是您已经很好理解的编程风格.

所以:为什么让一些Perl程序员更复杂(也慢得多)?答案是:它更灵活,更自我记录.

为了更清楚地说明,我在我们的函数定义中添加了SPECIAL_FEATURE.现在,函数也可以像这样调用:

$numRanges = buildRanges(VALUES => \@array, SPECIAL_FEATURE=> "infinite ranges");
Run Code Online (Sandbox Code Playgroud)

实现的函数可以告知请求SPECIAL_FEATURE并且不提供REF_RANGES.

在某些高级函数中,您有许多额外的功能,有时(但并非总是)有用,因此让调用者决定使用哪些功能以及哪些功能没有使用是很有意义的.在这里,命名参数派上用场.

当然,我不能告诉你有什么特殊的功能被认可的 buildRanges功能---你需要看它的实施或者提出告诉你要使用它的人.作为一般惯例,某些项目中的所有高级函数也可能使用这种调用样式,即使其中一些函数没有提供很多特殊功能.

  • 很好的解释,特别是因为你没有发现并且不知道OP的代码是什么. (3认同)