Arrays Perl:从子例程返回哈希

Arrays Perl:从子例程返回哈希,arrays,perl,hash,subroutine,Arrays,Perl,Hash,Subroutine,我已经尝试了几个小时的例子,但我似乎无法掌握如何做我想做的事情 我想从一个子例程返回一个散列,我认为引用是最好的选择。这里有点棘手。我想引用像$hash{$x}这样的散列。我仍然是perl的新手:/ 1.第一个问题,我使用的示例似乎表明使用$hashTable{$login}是可以的,我应该使用%hashTable{$login}还是不重要?代码如下: sub authUser { $LocalPath = "/root/UserData"; open(DATAFILE, "&

我已经尝试了几个小时的例子,但我似乎无法掌握如何做我想做的事情

我想从一个子例程返回一个散列,我认为引用是最好的选择。这里有点棘手。我想引用像$hash{$x}这样的散列。我仍然是perl的新手:/

1.第一个问题,我使用的示例似乎表明使用$hashTable{$login}是可以的,我应该使用%hashTable{$login}还是不重要?代码如下:

sub authUser  {
    $LocalPath = "/root/UserData";
    open(DATAFILE, "< $LocalPath");
    while( $linebuf = <DATAFILE> ) {
        chomp($linebuf);
        my @arr = split(/:/, $linebuf);
        my $login = $arr[1];        # arr[1] contains the user login names
        my $hashTable{ $login } = "$arr[0]";        #$arr[0] is account number
    }
    close DATAFILE;
    return \$hashTable{ $login };
}
2.如果我的$authHash真的是$authHash{$something},我对此很困惑

编辑:经过一些阅读技巧,仍在尝试,但没有骰子,任何帮助将不胜感激



编辑2:有人能修改我的代码以便我更好地理解答案吗?很抱歉,我似乎根本无法实现这一点,我已经尝试了几个小时,我真的想知道正确的方法,我可以发布我的各种尝试,但我觉得这将是对房地产的浪费。

首先,正如mpapec在评论中提到的,
使用严格;使用警告。这将捕获最常见的错误,包括标记您在这里询问的大多数问题(通常提供关于您应该做什么的提示)

现在回答问题1和2:

%hash
是整个hash。完整的数据结构

$hash{key}
是散列中的单个元素

因此,
\%hash
是对
%hash
的引用,即整个hash,在本例中它似乎是您想要返回的
\$hash{key}
是对单个元素的引用

在你的第二个问题中,最棘手的是引用总是标量,不管它们引用什么

$hash\u ref=\%hash

要从有引用的哈希中获取元素,首先需要取消引用它。这通常通过
->
操作符完成,如下所示:

$hash_ref->{key}

请注意,当您从引用(
$hash\u ref->{key}
)开始时,使用
->
,但当您从实际哈希(
$hash{key}
)开始时,不使用

(作为问题2的补充说明,不要在子调用前面加上
&
——只需使用
authUser()
而不是
&authUser()
&
在Perl 5+中不再需要,并且具有您通常不想要的副作用,因此您不应该养成在不需要的地方使用它的习惯。)

对于问题3,如果您只想检查一次,那么不妨在数组上循环并检查每个元素:

my $valid;
for my $username (@list_of_users) {
  if ($login eq $username) {
    $valid = 1;
    last; # end the loop since we found what we're looking for
  }
}

if ($valid) {
  print "Found valid username $login\n";
} else {
  print "Invalid user! $login does not exist!\n";
}

您可能不想这样做:

return \$hashTable{ $login };
您正在返回对哈希的引用(指针)。 试试看

return $hashTable{$login} 
这将返回帐号

或者如果你真的想和一群人一起吃杂烩

返回\$hashTable

很好(不要添加{$login}部分),但在另一方面,您需要 取消引用

例如:


注意->在那里。它反引用您传回的指针。

更清楚地说,Perl使用标量或标量列表:

$scalar = 1;
@list = ( $scalar, $scalar, $scalar );
@list2 =  @list1;            # copy all items
@list2 =  @list[ 1, 3..5 ];  # copy four items with index 1,3,4,5
@list2 =  @hash{ 'name1', 'name3' }; #copy two items with index 'name1', 'name2'
$scalar =  $hash2{ name1 }; # <--- What does this mean???
@list =  @hashTable{ 'login1', 'login2' };
# or
$l1 = 'login1';
$l2 = 'login2';
@list =  @hashTable{ $l1, $l2 };
列表中的每一项都可以通过索引访问,例如
$list[1]

您还可以按名称访问项目。此结构称为哈希:
$hash{name1}

%hash = ( 'name1', $scalar, 'name2', $scalar, 'name3', $scalar )
但是,正如你所看到的,这仍然是一个列表。注意它周围的“
()
”。
同样,列表中的每个项目只能是一个标量

$scalar = $$ref;
@list   = @$ref;
%hash   = %$ref;
我在任何一本书中都没有看到这一点,但是符号
$
表示一个值,@表示值列表。

在本例中,您有一个,因此使用$符号:

$scalar =  $hash{ name1 };
$scalar =  $list[ 1 ];
在下一个示例中,您有一个值列表,因此使用“@”:

Perl有引用。这是一个强大的工具

$ref = \$scalar;
$ref = \@list;
$ref = \%hash;
$ref
也是标量,因为它只有一个值。要访问此
$ref
引用的基础数据,应使用取消引用

$scalar = $$ref;
@list   = @$ref;
%hash   = %$ref;
但实际上,您不需要整个列表或散列。你只是想要一些东西。为此,您可以使用
->
[]
告诉Perl您想要访问列表元素,或者
{}
告诉Perl您想要访问散列元素:

$scalar = $ref->[ 1 ];
$scalar = $ref->{ name1 };
注意:您正在访问一个元素,因此使用了
$
符号。

如果需要数组或散列中的元素列表,可以使用
@
符号。例如:

@list =  @$ref[ 1, 3..5 ];
@list =  @$ref{ 'name1', 'name2' };
1st:$ref-返回对结构的引用$表示从变量“ref”获得一个值 第二:@$ref-您取消引用$ref。@表示您希望通过该引用访问项目列表。
3rd-a:从数组中获得“1,3,4,5”项(注意:
[]

3rd-b:从散列中获得'name1','name2'项(注意:
{}

但是,当您获取对散列或列表的引用并将此引用放置到另一个散列或数组时,我们可能会创建复杂的结构,例如散列数组或散列数组的散列。示例:

@list = ( 1, 2, 3, 4, 5 );
%hash = ( 'a', 1, b => 2 );
@list2 = ( \@list, \%hash, 3, 'y' );
%hash2 = ( name1 => \@list2, d => 4 );
%hash2 = ( 'name1', \@list2, 'd', 4 );  #same. no any difference.
$href  = \%hash2;
=>
-只需引用左操作数并在其后面加上

如果要访问“hash2”的一个项目,请执行以下操作:

$scalar =  $hash2{ name1 };
$scalar =  $href->{ name1 };
@list =  @hash2{ 'name1', 'd' };
@list =  @$href{ 'name1', 'd' };
取消引用后使用
$href->
将意味着
%hash2

如果要访问两个或多个“hash2”项,请执行以下操作:

$scalar =  $hash2{ name1 };
$scalar =  $href->{ name1 };
@list =  @hash2{ 'name1', 'd' };
@list =  @$href{ 'name1', 'd' };
在取消引用后使用
@$href
将意味着
%hash2

详细信息

$scalar = 1;
@list = ( $scalar, $scalar, $scalar );
@list2 =  @list1;            # copy all items
@list2 =  @list[ 1, 3..5 ];  # copy four items with index 1,3,4,5
@list2 =  @hash{ 'name1', 'name3' }; #copy two items with index 'name1', 'name2'
$scalar =  $hash2{ name1 }; # <--- What does this mean???
@list =  @hashTable{ 'login1', 'login2' };
# or
$l1 = 'login1';
$l2 = 'login2';
@list =  @hashTable{ $l1, $l2 };
$list\u ref
表示我们访问一个项目
->[
表示我们访问列表。因为
$list\u ref
指的是
@list2
,所以我们访问
\%hash
。我们可以通过一个步骤完成:

$scalar =  $hash2{ name1 }->[ 1 ];
$scalar =  $hash2{ name1 }->[ 1 ]->{ b };
当替换文本“$li”时,您可能会在此处思考
sub test {
    return @_;
}
return \%hash;  # fn()->{ name1 }; # actually all these is list of one item
return \@list;  # fn()->[ 1 ]; # so we may write: (fn())[0]->[ 1 ];
return $scalar; # fn(); # here also list of one item
return ( $scalar, \%hash, \@list ); 
    (fn())[ 0 ]; 
    (fn())[ 1 ]->{ name1 };
    (fn())[ 2 ]->[ 1 ];
@list =  @hashTable{ 'login1', 'login2' };
# or
$l1 = 'login1';
$l2 = 'login2';
@list =  @hashTable{ $l1, $l2 };
$login1 = { name => 'Vasiliy',   pass => 'secret' }  # ref to hash
%login2 = ( name => 'Petrovich', pass => '^&UDHJ' ); # just a hash
%hashTable = (
    vasya => $login1,  # items are always refs!!!
    piter => \%login2, # items are always refs!!!
)
my $authHash = authUser( 'vasya' ); # & is not required at all
if( $authHash->{ pass } eq $password ) {
...
}
my $usersDB =  loadUsers;

if( $usersDB->{ $login }->{ pass } eq $password ) {
     print 'You have granged access';
}
else { ... }
$list = [ 1, 2, 3 ];
$hash = { a => 1, b => 2 };
$list->[ 2 ];
$hash->{ b };
@l = @$list;
%h = %$hash;
@l = keys %$hash;
@l = values %$hash;