Subrutin Perl (fungsi)


Subrutin Perl ialah fungsi yang ditentukan pengguna.

Subrutin Perl ialah sekeping kod yang dipisahkan yang melaksanakan tugas khas Ia boleh mengurangkan kod berulang dan menjadikan program lebih mudah dibaca.

Subrutin Perl boleh muncul di mana-mana dalam atur cara Format sintaks adalah seperti berikut:

sub subroutine{
   statements;
}

Format sintaks untuk memanggil subrutin:

subroutine( 参数列表 );

Kaedah subrutin panggilan dalam versi di bawah Perl. 5.0 Seperti berikut:

&subroutine( 参数列表 );

Dalam versi baharu, walaupun kaedah panggilan ini turut disokong, penggunaannya tidak disyorkan.

Seterusnya mari kita lihat contoh mudah:

#!/usr/bin/perl

# 函数定义
sub Hello{
   print "Hello, World!\n";
}

# 函数调用
Hello();

Jalankan program di atas, hasil output ialah:

Hello, World!

Lepaskan parameter ke subrutin

Subrutin Perl boleh menerima berbilang parameter seperti parameter subrutin lain ditandakan dengan tatasusunan khas @_.

Jadi parameter pertama subrutin ialah $_[0], parameter kedua ialah $_[1] dan seterusnya.

Tidak kira sama ada parameter adalah skalar atau tatasusunan, apabila pengguna menghantar parameter ke subrutin, Perl akan memanggilnya secara rujukan secara lalai.

#!/usr/bin/perl

# 定义求平均值函数
sub Average{
   # 获取所有传入的参数
   $n = scalar(@_);
   $sum = 0;

   foreach $item (@_){
      $sum += $item;
   }
   $average = $sum / $n;
   print '传入的参数为 : ',"@_\n";           # 打印整个数组
   print "第一个参数值为 : $_[0]\n";         # 打印第一个参数
   print "传入参数的平均值为 : $average\n";  # 打印平均值
}

# 调用函数
Average(10, 20, 30);

Laksanakan atur cara di atas, hasil output ialah:

传入的参数为 : 10 20 30
第一个参数值为 : 10
传入参数的平均值为 : 20

Pengguna boleh menukar nilai parameter sebenar yang sepadan dengan menukar nilai dalam tatasusunan @_.

Melalukan senarai ke subrutin

Memandangkan pembolehubah @_ ialah tatasusunan, ia boleh menghantar senarai kepada subrutin.

Tetapi jika kita perlu menghantar parameter skalar dan tatasusunan, kita perlu meletakkan senarai pada parameter terakhir, seperti yang ditunjukkan di bawah:

#!/usr/bin/perl

# 定义函数
sub PrintList{
   my @list = @_;
   print "列表为 : @list\n";
}
$a = 10;
@b = (1, 2, 3, 4);

# 列表参数
PrintList($a, @b);

Atur cara di atas menggabungkan skalar dan tatasusunan serta output hasil Untuk:

列表为 : 10 1 2 3 4

Kita boleh menghantar berbilang tatasusunan dan cincang ke subrutin, tetapi apabila menghantar dalam berbilang tatasusunan dan cincang, identiti bebas akan hilang. Jadi kita perlu menggunakan rujukan (akan diperkenalkan dalam bab seterusnya) untuk lulus.

Melalukan cincang ke subrutin

Apabila jadual cincang dihantar ke subrutin, ia akan disalin ke @_ dan jadual cincang akan dikembangkan menjadi senarai gabungan kunci/nilai .

#!/usr/bin/perl

# 方法定义
sub PrintHash{
   my (%hash) = @_;

   foreach my $key ( keys %hash ){
      my $value = $hash{$key};
      print "$key : $value\n";
   }
}
%hash = ('name' => 'php', 'age' => 3);

# 传递哈希
PrintHash(%hash);

Output pelaksanaan program di atas ialah:

age : 3
name : php

Nilai pulangan subprogram

Subprogram boleh menggunakan pernyataan pulangan untuk mengembalikan nilai fungsi seperti pengaturcaraan lain bahasa.

Jika tiada pernyataan pemulangan digunakan, baris terakhir subrutin akan digunakan sebagai nilai pemulangan.

#!/usr/bin/perl

# 方法定义
sub add_a_b{
   # 不使用 return
   $_[0]+$_[1];  

   # 使用 return
   # return $_[0]+$_[1];  
}
print add_a_b(1, 2)

Output pelaksanaan program di atas ialah:

3

Dalam subrutin, kita boleh mengembalikan skalar, tatasusunan dan cincang, tetapi apabila mengembalikan berbilang tatasusunan dan cincang, nilai bebas akan menjadi logo hilang. Jadi kita perlu menggunakan rujukan (akan diperkenalkan dalam bab seterusnya) untuk mengembalikan berbilang tatasusunan dan fungsi.


Pembolehubah peribadi subrutin

Secara lalai, semua pembolehubah dalam Perl ialah pembolehubah global, yang bermaksud pembolehubah boleh dipanggil di mana-mana dalam atur cara.

Jika kita perlu menetapkan pembolehubah persendirian, kita boleh menggunakan operator my untuk menetapkannya. Pengendali

my digunakan untuk mencipta pembolehubah berskop leksikal yang dibuat melalui my bertahan dari permulaan pengisytiharan sehingga akhir skop tertutup.

Skop tertutup merujuk kepada kawasan dalam sepasang pendakap kerinting, ia boleh menjadi fail, atau ia boleh menjadi if, while, for, foreach, rentetan eval.

Contoh berikut menunjukkan cara untuk mengisytiharkan satu atau lebih pembolehubah peribadi:

sub somefunc {
   my $variable; # $variable 在方法 somefunc() 外不可见
   my ($another, @an_array, %a_hash); #  同时声明多个变量
}
#!/usr/bin/perl

# 全局变量
$string = "Hello, World!";

# 函数定义
sub PrintHello{
   # PrintHello 函数的私有变量
   my $string;
   $string = "Hello, php!";
   print "函数内字符串:$string\n";
}
# 调用函数
PrintHello();
print "函数外字符串:$string\n";

Output pelaksanaan program di atas ialah:

函数内字符串:Hello, php!
函数外字符串:Hello, World!

Penugasan sementara pembolehubah

Kita boleh menggunakan tempatan untuk menyediakan nilai sementara untuk pembolehubah global dan mengembalikan nilai asal selepas keluar dari skop.

pembolehubah tempatan yang ditakrifkan tidak wujud dalam program utama, tetapi wujud dalam subprogram dan subprogram yang dipanggil oleh subprogram. Anda boleh menetapkan nilai kepadanya semasa mentakrifkan, seperti:

#!/usr/bin/perl

# 全局变量
$string = "Hello, World!";

sub Printphp{
   # PrintHello 函数私有变量
   local $string;
   $string = "Hello, php!";
   # 子程序调用的子程序
   PrintMe();
   print "Printphp 函数内字符串值:$string\n";
}
sub PrintMe{
   print "PrintMe 函数内字符串值:$string\n";
}

sub PrintHello{
   print "PrintHello 函数内字符串值:$string\n";
}

# 函数调用
Printphp();
PrintHello();
print "函数外部字符串值:$string\n";

Hasil keluaran pelaksanaan program di atas ialah:

PrintMe 函数内字符串值:Hello, php!
Printphp 函数内字符串值:Hello, php!
PrintHello 函数内字符串值:Hello, World!
函数外部字符串值:Hello, World!

Pembolehubah statik

Fungsi bagi pengendali keadaan adalah serupa dengan dalam C Pengubah suai statik dan kata kunci keadaan menjadikan pembolehubah tempatan berterusan.

keadaan juga merupakan pembolehubah leksikal, jadi ia hanya sah dalam skop leksikal di mana pembolehubah itu ditakrifkan Contohnya:

#!/usr/bin/perl

use feature 'state';

sub PrintCount{
   state $count = 0; # 初始化变量

   print "counter 值为:$count\n";
   $count++;
}

for (1..5){
   PrintCount();
}

Hasil keluaran pelaksanaan program di atas ialah. :

counter 值为:0
counter 值为:1
counter 值为:2
counter 值为:3
counter 值为:4

Nota 1: keadaan hanya boleh mencipta pembolehubah yang skop tertutupnya berada di dalam subrutin.

Nota 2: keadaan telah diperkenalkan daripada Perl 5.9.4, jadi penggunaan mesti ditambah sebelum digunakan.

Nota 3: keadaan boleh mengisytiharkan skalar, tatasusunan dan cincang. Tetapi tatasusunan dan cincang tidak boleh dimulakan apabila ia diisytiharkan (sekurang-kurangnya tidak dalam Perl 5.14).


Konteks panggilan subrutin

Semasa proses panggilan subrutin, jenis nilai yang berbeza akan dikembalikan mengikut konteks Contohnya, subrutin localtime() berikut kembali dalam konteks skalar String, kembalikan senarai dalam konteks senarai:

#!/usr/bin/perl

# 标量上下文
my $datestring = localtime( time );
print $datestring;

print "\n";

# 列表上下文
($sec,$min,$hour,$mday,$mon, $year,$wday,$yday,$isdst) = localtime(time);
printf("%d-%d-%d %d:%d:%d",$year+1990,$mon+1,$mday,$hour,$min,$sec);

print "\n";

Hasil output pelaksanaan program di atas ialah:

Sun Jun 12 15:58:09 2016
2106-6-12 15:58:9