编程的新手.任务是从字符串中提取特定数据,我选择编写如下代码 -
while ($line =<IN>) {
chomp $line;
@tmp=(split /\t/, $line);
next if ($tmp[0] !~ /ch/);
@tgt1=@tmp[8..11];
@tgt2=@tmp[12..14];
@tgt3=@tmp[15..17];
@tgt4=@tmp[18..21];
foreach (1..4) {
print @tgt($_), "\n";
}
Run Code Online (Sandbox Code Playgroud)
我认为@tgt($_)
会被解释为@tgt1, @tgt2, @tgt3, @tgt4
但我仍然得到@tgt
一个全局符号的错误消息(@ tgt1,@ tgt2,@ tgt3,@ tgt4`已被声明).
Q1.我是否误解了foreach循环?
Q2.为什么perl看不到@tgt($_)
@ tgt1,@ tgt2 ..etc?
Q2.根据经验,这可能是命名变量的一种不好的方法.命名具有相似特征的变量的首选方法是什么?
Q2.为什么perl不能将@tgt($ _)视为@ tgt1,@ tgt2 ..etc?
Q2.根据经验,这可能是命名变量的一种不好的方法.命名具有相似特征的变量的首选方法是什么?
我会一起回答.
@tgt($_)
并不意味着你希望它意味着什么
首先,它是一个无效的语法(你不能在数组名后使用(),perl interpeter会产生编译错误).
你要做的是通过一个表达式访问一个变量来访问不同的变量,从而得到它的名字(也就是符号引用).这是可能的; 但通常是一个坏主意和糟糕的Perl(因为,你可以,但你不应该这样做,没有一个非常好的理由).
要以您尝试的方式访问元素$ _,请使用@{"tgt$_"}
语法.但我再说一遍 - 不要这样做,即使你可以.
一个正确的惯用解决方案:使用一个arrayrefs数组,你的1-4(或更确切地说是0-3)索引外部数组:
# Old bad code: @tgt1=@tmp[8..11];
# New correct code:
$tgt[0]=[ @tmp[8..11] ]; # [] creates an array reference from a list.
# etc... repeat 4 times - you can even do it in a smart loop later.
Run Code Online (Sandbox Code Playgroud)
这样做,它将对数组切片的引用存储到单个@tgt
数组的第0个元素中.
最后,@tgt
数组有4个元素,每个元素都是对包含其中一个片的数组的数组引用.
- Q1.我是否误解了foreach循环?
你的foreach循环(与其内容相反 - 见上文)是正确的,有一种风格警告 - 再次,当你可以使用默认$_
变量时,你几乎不应该使用它,而是总是使用命名变量来提高可读性.
您可以按如下方式打印上述arrayrefs数组(如果任何语法不清楚,请单独询问 - 这是一个中级数据结构处理,而不是初学者):
foreach my $index (0..3) {
print join(",", @{ $tgt[$index]}) . "\n";
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
93 次 |
最近记录: |