简体   繁体   English

Perl:这段代码怎么可能有效呢?

[英]Perl: How is it possible that this code is working?

my %hash = ('red' => "John", 'blue' => "Smith"); 
func (%hash);  

sub func {
    my $hash = $_[0];
    print "$hash{'red'}\n";
    print "$hash{'blue'}\n";
}

I send a hash to a subroutine, and this hash is treated as scalar. 我将哈希发送到子例程,并将此哈希视为标量。 If so, how is it possible that I can turn to a value in the hash by calling its key? 如果是这样,我怎么可能通过调用它的键来转向哈希值?

func(%hash);

is equivalent to 相当于

func('red', 'John', 'blue', 'Smith'); 
   -or-
func('blue', 'Smith', 'red', 'John'); 

so 所以

my $hash = $_[0];

is equivalent to 相当于

my $hash = 'red';
   -or-
my $hash = 'blue';

Totally useless. 完全没用。 Good thing you never use $hash ever again. 你永远不会再使用$hash好东西。


Instead, you use the %hash declared outside the sub. 相反,您使用在sub之外声明的%hash You can see this by reordering your code or by limiting the scope (visibility) of %hash . 您可以通过重新排序代码或限制%hash的范围(可见性)来查看此信息。

use strict;
use warnings;

{
    my %hash = ('red' => "John", 'blue' => "Smith"); 
    func(%hash);  
}

sub func {
    my $hash = $_[0];
    print "$hash{'red'}\n";
    print "$hash{'blue'}\n";
}

$ perl a.pl
Global symbol "%hash" requires explicit package name at a.pl line 11.
Global symbol "%hash" requires explicit package name at a.pl line 12.
Execution of a.pl aborted due to compilation errors.

The solution is to pass a reference. 解决方案是传递参考。

use strict;
use warnings;

{
    my %hash = ('red' => "John", 'blue' => "Smith"); 
    func(\%hash);
}

sub func {
    my $hash = $_[0];
    print "$hash->{'red'}\n";
    print "$hash->{'blue'}\n";
}

因为%hash的范围是整个程序。

%hash is supposed to be local. %hash应该是本地的。 no? 没有?

It's local to the enclosing scope. 它是封闭范围的本地。 Scopes are delimited by braces. 范围由大括号分隔。 But there are no braces anywhere surrounding your declaration: 但是你的宣言周围没有任何括号:

my %hash;

As a result, %hash is visible inside every nested scope in the file. 因此, %hash在文件中的每个嵌套范围内都是可见的。 Here is an example: 这是一个例子:

use strict;
use warnings;
use 5.016;

my $str = "hello";

if (1) { #new scope starts here
    say "if: $str";
} #scope ends here

{ #new scope starts here

    my $planet = "world";
    say "block: $str";

    for (1..2) { #new scope starts here
        say "for: $str $planet";
    } #scope ends here

} #scope ends here

#say $planet;  #The $planet that was previously declared isn't visible here, so this looks
               #like  you are trying to print a global variable, which results in a
               #compile error, because global variables are illegal with: use strict;


--output:--
if: hello
block: hello
for: hello world
for: hello world

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM