我对这个小代码片段感到困惑
my $ref = \@{$seq->{$label}{$ARGV[4]}};
能否帮助我解读一下?
(注:该代码涉及Perl语言中的引用和哈希表操作,其中$seq、$label和$ARGV[4]是变量名)
我对这个小代码片段感到困惑
my $ref = \@{$seq->{$label}{$ARGV[4]}};
能否帮助我解读一下?
my $ref = \@{
$seq->{ $label }{ $ARGV[4] }
}
外层的my $ref =
是一个赋值语句。我认为这很清楚。
然后@{ ... }
解引用括号中的内容作为数组,\
则取该数组的引用。引用取消了解引用,所以它与下面的表达式是相同的:
my $ref = $seq->{ $label }{ $ARGV[4] }
不是数组引用
现在我们有:
$seq->{ $label }{ $ARGV[4] }
这段代码使用$seq
作为哈希表的引用,将$label
作为第一级键,$ARGV[4]
(第五个命令行参数)作为第二级键。
这段代码由一个我会慷慨地称之为糟糕程序员的人编写。我怀疑它的目的是检查哈希值是否为数组引用,并且至少应该将$ARGV[4]
复制到一个命名变量中以使其含义清晰。
$seq
是一个哈希引用$seq->{$label}
返回解引用哈希中$label
键的值$ARGV[4]
键的值
@ARGV
是命令行参数的数组,$ARGV[4]
是索引为4的元素@{...}
解引用总结:在由$seq->{$label}
返回的哈希中,$ARGV[4]
键的值是指向数组的引用,整个过程可以按照下面的方式编写
my $ref = $seq->{$label}{$ARGV[4]};
请参考Borodin的回答,了解\@{$ref}
和$ref
之间的区别。
\@{$ref} == $ref
。没有复制。 - Borodin$ref
的内容时,\@{$ref}
是一种不好的方式。如果你有任何疑问,应该在使用它之前测试 ref $ref eq 'ARRAY'
。 - Borodinmy $ref = \@{$seq->{$label}{$ARGV[4]}};
$ARGV[4]
:通过命令行传递的第五个参数(例如:./perlscript.pl "argument1" "argument2" "argument3" "argument4" "argument5.txt"
)$seq->{ $label }{ $ARGV[4]}
:这里保存了一个数组引用,我们知道这一点是因为当您尝试用 @{ ... }
来解引用它时,否则会收到警告信息“Not an ARRAY reference”。另外,在变量的位置上,也可以使用裸字符串(例如:$seq->{ 'some label' }{ 'some other label'}
)@{ $seq->{ $label }{ $ARGV[4] } }
:这是进行解引用的操作,如#3所述\@{ $seq->{ $label }{ $ARGV[4] } }
:反斜杠使其再次成为一个引用,澄清了哈希表中保存的是数组引用my $ref = \@{ $seq->{ $label }{ $ARGV[4] } };
:标准的变量赋值 $seq
可以表示序列或任何其他内容, $label
不太可识别,并且像您所做的任何 $ARGV
一样,通常意味着其他地方未完成某些操作。
perl -E '$r = [ qw/ A B C / ]; $r2 = \@$r; $r2->[2] = q{X}; say qq{$r @$r $r2 @$r2}'
输出ARRAY(0x72c530) A B X ARRAY(0x72c530) A B X
。你可能在想$ref2 = [ @$ref ]
,它确实会产生一个浅拷贝。 - Borodin