编程的新手。任务是从字符串中提取特定数据,我选择编写代码如下 -
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";
}
我认为@tgt($_)
会被解释为@tgt1, @tgt2, @tgt3, @tgt4
,但我仍然会收到@tgt
是全局符号的错误消息(@ tgt1,@ tgt2,@ tgt3,@ tgt4`已宣布)。
Q1。我是否误解了foreach循环?
Q2。为什么perl看不到@tgt($_)
为@ tgt1,@ tgt2 ..etc?
Q2。根据经验,这可能是命名变量的一种不好的方法。命名具有相似特征的变量的首选方法是什么?
答案 0 :(得分:7)
Q2。为什么perl不能将@tgt($ _)视为@ tgt1,@ tgt2 ..etc?
Q2。根据经验,这可能是命名变量的一种不好的方法。命名具有相似特征的变量的首选方法是什么?
我会一起回答。
@tgt($_)
并不代表您希望的含义
首先,它是一个无效的语法(你不能在数组名后使用(),perl interpeter会产生编译错误)。
您要做的是通过表达式访问变量来访问不同的变量,从而产生其名称(又名symbolic references)。这是可能的;但通常是一个坏主意和糟糕的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.
这样做,它将对数组切片的引用存储到单个@tgt
数组的第0个元素中。
最后,@tgt
数组有4个元素,每个元素都是对包含其中一个切片的数组的数组引用。
- Q1。我是否误解了foreach循环?
你的foreach循环(与其内容相反 - 见上文)是正确的,有一种风格警告 - 再次,当你可以使用默认的$_
变量时,你几乎不应该使用它,而是总是使用命名变量的可读性。
你打印上面提到的arrayrefs数组如下(如果任何语法不清楚,请分别询问 - 这是一个中级数据结构处理,不适合初学者):
foreach my $index (0..3) {
print join(",", @{ $tgt[$index]}) . "\n";
}