参数与返回值 #
一、参数详解 #
1.1 @_ 数组 #
所有参数存储在 @_ 中:
perl
sub show_args {
print "Number of args: " . @_ . "\n";
print "Args: @_\n";
}
show_args("a", "b", "c");
1.2 直接访问参数 #
perl
sub add {
return $_[0] + $_[1];
}
print add(3, 5);
1.3 shift获取参数 #
perl
sub greet {
my $name = shift;
print "Hello, $name!\n";
}
greet("Tom");
1.4 多参数解包 #
perl
sub process {
my ($first, $second, @rest) = @_;
print "First: $first\n";
print "Second: $second\n";
print "Rest: @rest\n";
}
process(1, 2, 3, 4, 5);
1.5 哈希参数 #
perl
sub create_person {
my %args = @_;
print "Name: $args{name}\n";
print "Age: $args{age}\n";
}
create_person(
name => "Tom",
age => 25,
);
二、默认参数 #
2.1 使用 || 或 // #
perl
sub greet {
my $name = shift // "World";
print "Hello, $name!\n";
}
greet();
greet("Tom");
2.2 使用条件 #
perl
sub connect {
my %args = (
host => "localhost",
port => 3306,
@_,
);
print "Connecting to $args{host}:$args{port}\n";
}
connect();
connect(port => 3307);
connect(host => "192.168.1.1", port => 5432);
2.3 命名参数默认值 #
perl
sub configure {
my %args = @_;
my $host = $args{host} // "localhost";
my $port = $args{port} // 80;
my $debug = $args{debug} // 0;
print "Host: $host, Port: $port, Debug: $debug\n";
}
configure(debug => 1);
三、上下文 #
3.1 标量上下文 vs 列表上下文 #
perl
my @arr = localtime();
my $scalar = localtime();
print "List: @arr\n";
print "Scalar: $scalar\n";
3.2 wantarray #
检测调用上下文:
perl
sub get_data {
if (wantarray) {
return (1, 2, 3, 4, 5);
} else {
return 5;
}
}
my @list = get_data();
my $count = get_data();
print "List: @list\n";
print "Count: $count\n";
3.3 实际应用 #
perl
sub file_lines {
my $file = shift;
open my $fh, "<", $file or return;
if (wantarray) {
return <$fh>;
} else {
local $/;
return <$fh>;
}
}
my @lines = file_lines("test.txt");
my $content = file_lines("test.txt");
四、引用参数 #
4.1 传递数组引用 #
perl
sub process_array {
my $arr_ref = shift;
foreach my $item (@$arr_ref) {
print $item . "\n";
}
}
my @data = (1, 2, 3, 4, 5);
process_array(\@data);
4.2 传递哈希引用 #
perl
sub show_person {
my $person = shift;
print "Name: $person->{name}\n";
print "Age: $person->{age}\n";
}
my %tom = (name => "Tom", age => 25);
show_person(\%tom);
4.3 修改参数 #
perl
sub increment {
my $ref = shift;
$$ref++;
}
my $count = 0;
increment(\$count);
increment(\$count);
print $count;
4.4 原地修改数组 #
perl
sub double_values {
my $arr = shift;
$_ *= 2 foreach @$arr;
}
my @nums = (1, 2, 3, 4, 5);
double_values(\@nums);
print "@nums\n";
五、返回引用 #
5.1 返回数组引用 #
perl
sub get_numbers {
my @arr = (1, 2, 3, 4, 5);
return \@arr;
}
my $nums = get_numbers();
print "@$nums\n";
5.2 返回哈希引用 #
perl
sub create_person {
my ($name, $age) = @_;
return {
name => $name,
age => $age,
};
}
my $person = create_person("Tom", 25);
print "Name: $person->{name}\n";
5.3 返回子程序引用 #
perl
sub create_counter {
my $count = 0;
return sub {
return ++$count;
};
}
my $counter = create_counter();
print $counter->() . "\n";
print $counter->() . "\n";
print $counter->() . "\n";
六、原型 #
6.1 基本原型 #
perl
sub my_push (\@@) {
my $arr = shift;
push @$arr, @_;
}
my @arr;
my_push @arr, 1, 2, 3;
print "@arr\n";
6.2 常用原型 #
| 原型 | 说明 |
|---|---|
| $ | 标量 |
| @ | 数组 |
| % | 哈希 |
| & | 子程序 |
| * | 类型通配符 |
| \ | 引用 |
perl
sub run_code (&) {
my $code = shift;
$code->();
}
run_code { print "Hello!\n" };
6.3 不推荐使用原型 #
现代Perl推荐避免使用原型,除非有特殊需求。
七、实践练习 #
练习1:灵活参数 #
perl
#!/usr/bin/perl
use strict;
use warnings;
use v5.10;
sub search {
my %opts = (
pattern => "",
case_sensitive => 0,
@_,
);
my $text = shift // "";
my $pattern = $opts{pattern};
my $flags = $opts{case_sensitive} ? "" : "i";
my @matches = $text =~ /($pattern)/$flags;
return @matches;
}
my $text = "Hello Perl World";
my @matches = search($text, pattern => "perl", case_sensitive => 0);
say "Matches: @matches";
练习2:上下文感知函数 #
perl
#!/usr/bin/perl
use strict;
use warnings;
use v5.10;
sub range {
my ($start, $end) = @_;
if (wantarray) {
return ($start..$end);
} else {
return $end - $start + 1;
}
}
my @numbers = range(1, 10);
my $count = range(1, 10);
say "Numbers: @numbers";
say "Count: $count";
练习3:回调函数 #
perl
#!/usr/bin/perl
use strict;
use warnings;
use v5.10;
sub process_items {
my ($items, $callback) = @_;
my @results;
foreach my $item (@$items) {
push @results, $callback->($item);
}
return @results;
}
my @numbers = (1, 2, 3, 4, 5);
my @doubled = process_items(\@numbers, sub {
my $n = shift;
return $n * 2;
});
my @squared = process_items(\@numbers, sub {
my $n = shift;
return $n ** 2;
});
say "Original: @numbers";
say "Doubled: @doubled";
say "Squared: @squared";
八、总结 #
本章学习了:
- 参数传递详解
- 默认参数
- 上下文感知(wantarray)
- 引用参数
- 返回引用
- 原型
下一章将学习作用域与闭包。
最后更新:2026-03-27