Arrays 为什么这会复制或覆盖列表的内容?
我是Perl新手,我不太明白我的代码出了什么问题。我相信我正确地使用了语法,但我怀疑问题可能出在这一行:Arrays 为什么这会复制或覆盖列表的内容?,arrays,perl,list,hash,push,Arrays,Perl,List,Hash,Push,我是Perl新手,我不太明白我的代码出了什么问题。我相信我正确地使用了语法,但我怀疑问题可能出在这一行: push @students, \%information; 我想让学生列表包含学生信息的散列。我所期望的是,在每次添加student之后,会创建另一个学生信息散列,并链接到列表的最新索引。但是如果我同时输入学生数据,最新的会覆盖上一个,所以当你打印它时,你会在上一个列表条目中看到最新输入信息的副本。如果我输入一个学生并在添加后立即查看,然后输入另一个学生,则最新的学生将覆盖前一个学生。有
push @students, \%information;
我想让学生列表包含学生信息的散列。我所期望的是,在每次添加student之后,会创建另一个学生信息散列,并链接到列表的最新索引。但是如果我同时输入学生数据,最新的会覆盖上一个,所以当你打印它时,你会在上一个列表条目中看到最新输入信息的副本。如果我输入一个学生并在添加后立即查看,然后输入另一个学生,则最新的学生将覆盖前一个学生。有人能解释一下吗?谢谢大家!
这是我的密码:
use strict;
use warnings;
my $userchoice = 0;
my $i;
my @students = (); #empty array
my %information = ();
while ( $userchoice != 4 ) {
print "------------------------------\n";
print "Welcome! What would you like to do?\n";
print "[0]Create Student Record\n";
print "[1]Edit Student Record\n";
print "[2]View Student Record\n";
print "[3]Delete Student Record\n";
print "[4]Exit\n";
print "Your Choice : ";
$userchoice = <STDIN>;
chomp($userchoice);
if ( $userchoice == 0 ) {
print "-----------\n";
print "CREATE STUDENT RECORD.\n";
if ( $#students <= 9 ) {
print "Name : ";
$information{"name"} = <STDIN>;
chomp( $information{"name"} );
push @students, \%information;
}
print "Student Record Full. " if ( $#students >= 10 );
}
if ( $userchoice == 2 ) {
print "\nVIEW STUDENTS.\n";
print "[0]View One Student\n";
print "[1]View All Students\n";
print "[2]Back to Main Menu\n";
print "Your Choice : ";
$userchoice = <STDIN>;
if ( $userchoice == 1 ) {
print "VIEW ALL STUDENTS.\n";
print "STUDENT 1---------------\n";
print "Name : ", $students[0]->{"name"}, " \n";
print "STUDENT 2---------------\n";
print "Name : ", $students[1]->{"name"}, " \n";
}
}
}
使用严格;
使用警告;
我的$userchoice=0;
我的$i;
我的@students=()#空数组
我的%信息=();
而($userchoice!=4){
打印“-----------------------------------\n”;
打印“欢迎!您想做什么?\n”;
打印“[0]创建学生记录\n”;
打印“[1]编辑学生记录\n”;
打印“[2]查看学生记录\n”;
打印“[3]删除学生记录\n”;
打印“[4]退出\n”;
打印“您的选择:”;
$userchoice=;
chomp($userchoice);
如果($userchoice==0){
打印“------------\n”;
打印“创建学生记录。\n”;
如果($#学生=10),;
}
如果($userchoice==2){
打印“\n查看学生。\n”;
打印“[0]查看一名学生\n”;
打印“[1]查看所有学生\n”;
打印“[2]返回主菜单\n”;
打印“您的选择:”;
$userchoice=;
如果($userchoice==1){
打印“查看所有学生。\n”;
打印“学生1---------\n”;
打印“姓名:”,$students[0]->{“姓名”},“\n”;
打印“学生2------------------\n”;
打印“姓名:”,$students[1]->{“姓名”},“\n”;
}
}
}
这总是将对同一哈希的引用推送到数组push@students,\%信息代码>
举例说明:
my %hash = ( index => 0 );
my @list = ();
foreach my $i (1..3) {
$hash{index} = $i;
push @list, \%hash;
}
for ( my $i=0; $i<@list; $i++ ) {
print "item $i - $list[$i] - $list[$i]->{index}\n";
}
您可以通过在循环中声明%信息进行修复
while($userchoice!=4){
my %information = ();
或者在推送时强制执行新引用:
push @students, { %information };
如评论中所述:
您需要每次使用对新哈希的引用,而不是每次尝试引用同一个哈希。最简单的方法是在循环体中定义%信息
您的代码当前为:
my %information = ();
while ( $userchoice != 4 ) {
print "------------------------------\n";
如果您使用以下方法,它将正常工作(或者至少,它的这一方面将正常工作):
while ( $userchoice != 4 ) {
my %information = ();
print "------------------------------\n";
出现问题的原因是您在数组中为每个学生放置了对相同哈希的引用:
push @students, \%information;
解决此问题的一个方法是为每个记录创建一个新的匿名哈希:
push @students, { %information };
然而,我相信你也可以从中吸取教训,限制变量的范围
声明变量时始终使用尽可能小的范围。这既有助于记录代码,也减少了意外误用此类变量的机会
以下是重写脚本以删除全局作用域中使用的所有变量:
use strict;
use warnings;
my @students = (); #empty array
while (1) {
print "------------------------------\n";
print "Welcome! What would you like to do?\n";
print "[0]Create Student Record\n";
print "[1]Edit Student Record\n";
print "[2]View Student Record\n";
print "[3]Delete Student Record\n";
print "[4]Exit\n";
print "Your Choice : ";
chomp( my $userchoice = <STDIN> );
last if $userchoice == 4;
if ( $userchoice == 0 ) {
print "-----------\n";
print "CREATE STUDENT RECORD.\n";
if ( @students <= 10 ) {
print "Name : ";
chomp( my $name = <STDIN> );
push @students, { name => $name };
}
print "Student Record Full. " if ( @students > 10 );
}
if ( $userchoice == 2 ) {
print "\nVIEW STUDENTS.\n";
print "[0]View One Student\n";
print "[1]View All Students\n";
print "[2]Back to Main Menu\n";
print "Your Choice : ";
chomp( my $userchoice = <STDIN> );
if ( $userchoice == 1 ) {
print "VIEW ALL STUDENTS.\n";
for my $i ( 1 .. @students ) {
print "STUDENT $i---------------\n";
print "Name : ", $students[ $i - 1 ]{"name"}, " \n";
}
}
}
}
使用严格;
使用警告;
我的@students=()#空数组
而(1){
打印“-----------------------------------\n”;
打印“欢迎!您想做什么?\n”;
打印“[0]创建学生记录\n”;
打印“[1]编辑学生记录\n”;
打印“[2]查看学生记录\n”;
打印“[3]删除学生记录\n”;
打印“[4]退出\n”;
打印“您的选择:”;
chomp(我的$userchoice=);
如果$userchoice==4,则为最后一个;
如果($userchoice==0){
打印“------------\n”;
打印“创建学生记录。\n”;
如果(@students$name};
}
如果(@students>10),则打印“学生记录已满”;
}
如果($userchoice==2){
打印“\n查看学生。\n”;
打印“[0]查看一名学生\n”;
打印“[1]查看所有学生\n”;
打印“[2]返回主菜单\n”;
打印“您的选择:”;
chomp(我的$userchoice=);
如果($userchoice==1){
打印“查看所有学生。\n”;
我的$i(1..@students){
打印“学生$i---------\n”;
打印“姓名:”,$students[$i-1]{“姓名”},“\n”;
}
}
}
}
你每次都需要引用一个新的散列,而不是每次都尝试引用同一个散列。最简单的方法是在循环体中定义%信息。
得到了修复!感谢Jonathan。它确实被复制了,因为列表将引用排序为相同的散列…谢谢!到底是什么我做到了,之后效果很好。谢谢你提供更多的细节!谢谢你提供的有用提示。我会记住的。
use strict;
use warnings;
my @students = (); #empty array
while (1) {
print "------------------------------\n";
print "Welcome! What would you like to do?\n";
print "[0]Create Student Record\n";
print "[1]Edit Student Record\n";
print "[2]View Student Record\n";
print "[3]Delete Student Record\n";
print "[4]Exit\n";
print "Your Choice : ";
chomp( my $userchoice = <STDIN> );
last if $userchoice == 4;
if ( $userchoice == 0 ) {
print "-----------\n";
print "CREATE STUDENT RECORD.\n";
if ( @students <= 10 ) {
print "Name : ";
chomp( my $name = <STDIN> );
push @students, { name => $name };
}
print "Student Record Full. " if ( @students > 10 );
}
if ( $userchoice == 2 ) {
print "\nVIEW STUDENTS.\n";
print "[0]View One Student\n";
print "[1]View All Students\n";
print "[2]Back to Main Menu\n";
print "Your Choice : ";
chomp( my $userchoice = <STDIN> );
if ( $userchoice == 1 ) {
print "VIEW ALL STUDENTS.\n";
for my $i ( 1 .. @students ) {
print "STUDENT $i---------------\n";
print "Name : ", $students[ $i - 1 ]{"name"}, " \n";
}
}
}
}