📜  珀尔 |对子例程的引用

📅  最后修改于: 2022-05-13 01:55:21.664000             🧑  作者: Mango

珀尔 |对子例程的引用

先决条件: Perl 参考

声明对子例程的引用

在 Perl 中,引用正如其名称所暗示的那样,是指向另一个对象的引用或指针。引用实际上提供了各种其他方式无法获得的能力和设施,可用于创建复杂的结构,例如调度表高阶过程闭包等。对于第一次使用 Perl 的 C 程序员,参考是完全像一个指针,除了在 Perl 中它更容易使用,更重要的是,更实用。有两种类型的引用: symbolichard
符号引用使您能够使用另一个变量的值作为按名称对变量的引用。例如,如果变量 $val 包含字符串“Text”,则对 $val 的符号引用指的是变量 $Text。
引用是数据结构中包含的实际数据的术语。然而,它指向的数据结构的形式在很大程度上是无关紧要的。尽管硬引用可以引用单个标量,但它也可以引用标量数组、散列或子例程。

$val = "Text";
$val_ref = \$val;

# For other variables
$array = \@ARGV;
$hash = \%ENV;

# For reference to subroutine
sub val { print "val" };
$valsub = \&val;

调用子程序参考

调用子例程引用也称为取消引用。这是从结构中提取信息的行为。当您取消引用标量引用时,您实际上是在引用原始数据结构。取消引用的最直接方法是在包含引用的标量变量之前添加您期望的相关数据类型字符(标量为$ ,数组为@ ,哈希为% ,子例程为& )。

$val_ref = \$val;       # Create reference to scalar
$array = \@ARGV;        # Create reference to array
$hash = \%ENV;          # Create reference to hash
$valsub = \&            # Create reference to subroutine

# Dereferencing
$$val_ref;
$$array[0, 1, ....];
$$hash{'...'};
&$valsub;

子例程既可以命名也可以匿名。 Perl 提供了声明对这两种子例程类型的引用和取消引用它们的工具。
示例 1:

perl
#!/usr/bin/perl
 
# Perl program to demonstrate
# reference to subroutines
 
# Creating a named subroutine
sub name
{
    return "GeeksforGeeks";
}
 
# Create callable reference
# to named subroutine
$rs1 = \&name;    
print("Reference to named subroutine: ", $rs1);
print("\nAfter dereferencing, value : ", &$rs1);
 
# Create a reference to an
# anonymous subroutine
$rs2 = sub{
               return "GFG";
          };
print("\n");
print("\nReference to anonymous subroutine: ", $rs2);
print("\nAfter dereferencing, value : ", &$rs2);


perl
#!/usr/bin/perl
 
# Perl program to demonstrate
# reference to subroutines
 
$rs = \&func1;
 
# Prints "GeeksforGeeks"
$rs->("Geeks")->("for")->("Geeks");    
 
sub func1
{
    my $val = shift;
    print "$val";
    return \&func2;
}
 
sub func2
{
    my $val = shift;
    print "$val";
    return \&func3;
}
 
sub func3
{
    my $val = shift;
    print "$val\n";
}


Perl
# Perl program to demonstrate
# the use of callbacks
sub alt {
            print "$a $b\n";
            $arr{$a} cmp $arr{$b};
        }
 
%arr = ("Marcelo", "Lewis",
        "Rodrygo", "Peter",
        "Sandro", "James");
 
# @names = sort alt (keys(%arr));
@names = calc ("Alternate", keys(%arr));
foreach $person (@names)
{
    print "$person teams up with $arr{$person}\n";
}
 
# Example code to show
# what really goes on inside sort.
sub calc
{
    my ($subn, @final) = @_;
    for ($k = 0; $k < $final; $k++)
    {
        $count = 0;
        for ($j = 0; $j < $final - $k; $j++)
        {
            $a = $final[$j];
            $b = $final[$j + 1];
            if (&{$subn}() > 0 )
            {
                $final[$j] = $b;
                $final[$j + 1] = $a;
                $count++;
            }
        }
        last unless ($count);
    }
    return @final
}


perl
w
# Perl program to demonstrate
# array of references
 
# Declaring a reference to a nested array
$array = [[1, 2, 3, 4, 5],
          ['Geeks', 'for', 'Geeks'],
          [6, 7, 8, 9]];
 
# Access element using index
# Dereferencing performed
print("$$array[1][2]");    
 
# Access element using infix method
print("\n$array->[1][1]");
print("\n$array->[1]->[0]");
 
# Printing complete nested array
print("\nElements in the array are :");
print("\n");
for(my $i = 0; $i < scalar(@{$array}); $i++)
{
    for(my $j = 0; 
           $j < scalar(@{$array->[$i]}); $j++)
    {
        print($$array[$i][$j]);
        print(" ");
    }
    print("\n");
}


perl
#!/usr/bin/perl
 
# Perl program to demonstrate
# array of references
use strict;
use warnings;
 
my %friends = ( 1 => 'John',     4 => 'Sandro',
                2 => 'Rodrygo', 5 => 'Peter',
                3 => 'Marcelo', 6 => 'Luis' );
 
# Declaring a Reference to the hash
my $hash_ref = \%friends;
 
# Access element from hash using key value
print("$$hash_ref{1}\n");     # prints John
 
# Acces element using infix operation
print("$hash_ref->{3}\n");
 
# Print all elements of the hash
# with their keys
print ("The hash stored is :\n");
 
for (keys %$hash_ref)
{
    print("$_ = $hash_ref->{$_}\n");
}


输出
Reference to named subroutine: CODE(0x981750)
After dereferencing, value : GeeksforGeeks

Reference to anonymous subroutine: CODE(0x981870)
After dereferencing, value : GFG

操作的使用如下例所示。中缀操作提供了一种从复杂或嵌套结构中提取信息的更好、更简单的方法。
示例 2:

perl

#!/usr/bin/perl
 
# Perl program to demonstrate
# reference to subroutines
 
$rs = \&func1;
 
# Prints "GeeksforGeeks"
$rs->("Geeks")->("for")->("Geeks");    
 
sub func1
{
    my $val = shift;
    print "$val";
    return \&func2;
}
 
sub func2
{
    my $val = shift;
    print "$val";
    return \&func3;
}
 
sub func3
{
    my $val = shift;
    print "$val\n";
}
输出:
GeeksforGeeks

回调

回调是开发 Perl Tk 接口时应该记住的重要元素之一。当我们到达某个条件点或执行某个操作时,它会从脚本的另一部分回调一段代码。
回调有点像代码的延迟执行,它是由事件触发的,而不是以线性方式执行事物。对于此类事件驱动的代码功能,我们经常在需要时使用子程序引用来调用此类代码。
例子:

Perl

# Perl program to demonstrate
# the use of callbacks
sub alt {
            print "$a $b\n";
            $arr{$a} cmp $arr{$b};
        }
 
%arr = ("Marcelo", "Lewis",
        "Rodrygo", "Peter",
        "Sandro", "James");
 
# @names = sort alt (keys(%arr));
@names = calc ("Alternate", keys(%arr));
foreach $person (@names)
{
    print "$person teams up with $arr{$person}\n";
}
 
# Example code to show
# what really goes on inside sort.
sub calc
{
    my ($subn, @final) = @_;
    for ($k = 0; $k < $final; $k++)
    {
        $count = 0;
        for ($j = 0; $j < $final - $k; $j++)
        {
            $a = $final[$j];
            $b = $final[$j + 1];
            if (&{$subn}() > 0 )
            {
                $final[$j] = $b;
                $final[$j + 1] = $a;
                $count++;
            }
        }
        last unless ($count);
    }
    return @final
}
输出:
Sandro teams up with James
Rodrygo teams up with Peter
Marcelo teams up with Lewis

上面的示例描述了使用回调函数calc根据散列中保存的值中的字符数(长度)对散列键列表进行排序。

引用的数组和哈希

除了数组和散列的常规约束之外,您还可以创建由两者组合而成的复杂结构。这些是嵌套的或复杂的结构,它们可用于以易于使用的格式对复杂数据进行建模。嵌套结构实际发生的情况是 Perl 将嵌套数据类型存储为对匿名变量的引用。例如,在二维数组中,主数组是引用列表,子数组是这些引用指向的匿名数组。这意味着“数组数组”实际上是指对数组的引用数组。所有嵌套结构都是如此;而且,虽然它看起来很复杂,但它确实提供了一种适当强大的方法来创建复杂的嵌套结构。
示例 1:

perl

w
# Perl program to demonstrate
# array of references
 
# Declaring a reference to a nested array
$array = [[1, 2, 3, 4, 5],
          ['Geeks', 'for', 'Geeks'],
          [6, 7, 8, 9]];
 
# Access element using index
# Dereferencing performed
print("$$array[1][2]");    
 
# Access element using infix method
print("\n$array->[1][1]");
print("\n$array->[1]->[0]");
 
# Printing complete nested array
print("\nElements in the array are :");
print("\n");
for(my $i = 0; $i < scalar(@{$array}); $i++)
{
    for(my $j = 0; 
           $j < scalar(@{$array->[$i]}); $j++)
    {
        print($$array[$i][$j]);
        print(" ");
    }
    print("\n");
}
输出:
Geeks
for
Geeks
Elements in the array are :
1 2 3 4 5 
Geeks for Geeks 
6 7 8 9

示例 2:

perl

#!/usr/bin/perl
 
# Perl program to demonstrate
# array of references
use strict;
use warnings;
 
my %friends = ( 1 => 'John',     4 => 'Sandro',
                2 => 'Rodrygo', 5 => 'Peter',
                3 => 'Marcelo', 6 => 'Luis' );
 
# Declaring a Reference to the hash
my $hash_ref = \%friends;
 
# Access element from hash using key value
print("$$hash_ref{1}\n");     # prints John
 
# Acces element using infix operation
print("$hash_ref->{3}\n");
 
# Print all elements of the hash
# with their keys
print ("The hash stored is :\n");
 
for (keys %$hash_ref)
{
    print("$_ = $hash_ref->{$_}\n");
}
输出:
John
Marcelo
The hash stored is :
4 = Sandro
1 = John
2 = Rodrygo
5 = Peter
3 = Marcelo
6 = Luis