Perl 变量
变量声明
使用 my 声明局部变量
my 声明的是词法作用域的局部变量,只在当前作用域内可见:
perl
use strict;
use warnings;
my $name = "Alice"; # 声明并初始化
my $age; # 声明但不初始化
$age = 25; # 赋值
{
my $inner = "inside"; # 只在这个块内有效
print "$inner\n"; # 输出:inside
}
# print $inner; # 错误:$inner 在这里不可见使用 our 声明全局变量
our 声明的是全局变量,可以在整个包中使用:
perl
use strict;
use warnings;
our $global_var = "global";
sub show_global {
print "$global_var\n"; # 可以访问
}
show_global(); # 输出:global使用 local 临时修改变量
local 临时改变全局变量的值,在当前作用域结束后恢复原值:
perl
use strict;
use warnings;
our $var = "original";
{
local $var = "modified";
print "Inside: $var\n"; # 输出:modified
}
print "Outside: $var\n"; # 输出:original变量作用域
词法作用域(Lexical Scope)
使用 my 声明的变量具有词法作用域:
perl
use strict;
use warnings;
my $x = 10; # 全局词法变量
sub sub1 {
my $x = 20; # 遮蔽外部的 $x
print "sub1: $x\n"; # 输出:20
}
sub sub2 {
print "sub2: $x\n"; # 输出:10
}
sub1();
sub2();动态作用域(Dynamic Scope)
使用 local 的变量具有动态作用域:
perl
use strict;
use warnings;
our $var = "global";
sub sub1 {
local $var = "in sub1";
sub2();
}
sub sub2 {
print "sub2 sees: $var\n"; # 输出:in sub1
}
sub1();
print "main sees: $var\n"; # 输出:global变量命名规则
命名规则
perl
# 合法的变量名
my $name;
my $user_name;
my $userName;
my $name123;
# 错误的变量名
# my $1name; # 不能以数字开头
# my $user-name; # 不能包含连字符
# my $user name; # 不能包含空格命名约定
perl
# 标量:小写字母,单词间用下划线
my $user_name = "Alice";
my $email_address = "alice@example.com";
# 布尔变量:以 is_ 或 has_ 开头
my $is_valid = 1;
my $has_permission = 0;
# 数组:复数形式
my @users = ("Alice", "Bob", "Charlie");
my @file_names = ("file1.txt", "file2.txt");
# 哈希:复数形式或带 _data 后缀
my %user_data = (name => "Alice", age => 25);
my %config = (host => "localhost", port => 8080);变量赋值
基本赋值
perl
my $name = "Alice";
my $age = 25;
my $is_valid = 1;列表赋值
perl
# 多个变量同时赋值
my ($name, $age, $city) = ("Bob", 30, "London");
print "$name, $age, $city\n"; # Bob, 30, London
# 数组赋值
my @colors = ("red", "green", "blue");
my ($red, $green, $blue) = @colors;
# 部分赋值
my ($first, $second) = (1, 2, 3, 4, 5);
print "$first, $second\n"; # 1, 2
# 交换变量值
my $a = 10;
my $b = 20;
($a, $b) = ($b, $a);
print "a=$a, b=$b\n"; # a=20, b=10哈希赋值
perl
my %person = (
name => "Alice",
age => 25,
city => "New York"
);
# 添加键值对
$person{email} = "alice@example.com";
# 修改值
$person{age} = 26;默认值
undef 值
未初始化的标量值为 undef:
perl
use strict;
use warnings;
my $value;
print defined($value) ? "defined" : "undef"; # 输出:undef
# 在数值上下文中,undef 变为 0
my $num = $value + 10; # $num = 10
# 在字符串上下文中,undef 变为空字符串
my $str = "value: " . $value; # $str = "value: "设置默认值
perl
# 使用 || 运算符
my $name = $input_name || "Anonymous";
# 使用 //= 运算符(Perl 5.10+)
my $email //= "no-email@example.com";
# 使用 defined-or 运算符
my $age = defined($user_age) ? $user_age : 0;
# 在函数中使用默认参数
sub greet {
my ($name, $greeting) = @_;
$name //= "World";
$greeting //= "Hello";
print "$greeting, $name!\n";
}特殊变量
默认变量 $_
perl
# 在循环中
foreach (1..5) {
print; # 等同于 print $_
}
# 在模式匹配中
$_ = "Hello World";
/World/; # 等同于 $_ =~ /World/
# 默认输入
while (<STDIN>) {
print; # 输出读取的行
}列表分隔符 $"
perl
$" = ", "; # 设置数组内插时的分隔符
my @array = (1, 2, 3);
print "@array\n"; # 输出:1, 2, 3输入记录分隔符 $/
perl
$/ = ""; # 段落模式
$/ = "\n"; # 行模式(默认)
# 读取整个文件
$/ = undef;
my $content = <FILE>;输出记录分隔符 $\
perl
$\ = "\n"; # 自动添加换行符
print "Hello"; # 输出:Hello\n输出字段分隔符 $,
perl
$, = ", ";
print "a", "b", "c"; # 输出:a, b, c变量引用
创建引用
perl
# 标量引用
my $scalar = 42;
my $scalar_ref = \$scalar;
print $$scalar_ref; # 输出:42
# 数组引用
my @array = (1, 2, 3);
my $array_ref = \@array;
print @$array_ref; # 输出:123
# 哈希引用
my %hash = (name => "Alice");
my $hash_ref = \%hash;
print $hash_ref->{name}; # 输出:Alice
# 匿名数组引用
my $anon_array = [1, 2, 3];
# 匿名哈希引用
my $anon_hash = {name => "Bob", age => 30};解引用
perl
# 方法 1:使用 $ 和 @ 或 %
my $array_ref = [1, 2, 3];
my @array = @$array_ref;
# 方法 2:使用箭头运算符
my $first = $array_ref->[0]; # 访问第一个元素
# 哈希解引用
my $hash_ref = {name => "Alice"};
my %hash = %$hash_ref;
print $hash_ref->{name}; # 输出:Alice常量
使用 constant
perl
use constant {
PI => 3.14159,
MAX_USERS => 100,
API_KEY => "abc123"
};
print PI; # 输出:3.14159
print MAX_USERS; # 输出:100
# PI = 3.14; # 错误:不能修改常量使用 Readonly
perl
use Readonly;
Readonly my $PI => 3.14159;
Readonly my @DAYS => qw(Monday Tuesday Wednesday);
Readonly my %CONFIG => (host => "localhost", port => 8080);
print $PI; # 输出:3.14159
print @DAYS; # 输出:MondayTuesdayWednesday实践示例
示例 1:变量作用域演示
perl
#!/usr/bin/perl
use strict;
use warnings;
my $global = "global scope";
sub demo_scope {
my $local = "local scope";
print "Inside sub: $global, $local\n";
}
demo_scope(); # 输出:Inside sub: global scope, local scope
print "Outside sub: $global\n";
# print $local; # 错误:$local 在这里不可见示例 2:引用使用
perl
#!/usr/bin/perl
use strict;
use warnings;
# 创建哈希数组
my @users = (
{name => "Alice", age => 25},
{name => "Bob", age => 30},
{name => "Charlie", age => 35}
);
foreach my $user (@users) {
printf "%-10s: %d years old\n", $user->{name}, $user->{age};
}示例 3:默认值处理
perl
#!/usr/bin/perl
use strict;
use warnings;
sub get_user_info {
my ($name, $email, $age) = @_;
$name //= "Unknown";
$email //= "no-email@example.com";
$age //= 0;
return {
name => $name,
email => $email,
age => $age
};
}
my $info1 = get_user_info("Alice");
my $info2 = get_user_info("Bob", "bob@example.com");
my $info3 = get_user_info("Charlie", "charlie@example.com", 25);
foreach my $info ($info1, $info2, $info3) {
printf "Name: %-10s Email: %-20s Age: %d\n",
$info->{name}, $info->{email}, $info->{age};
}小结
本章节学习了 Perl 的变量:
- ✅ 变量声明(my、our、local)
- ✅ 变量作用域(词法作用域、动态作用域)
- ✅ 变量命名规则和约定
- ✅ 变量赋值和默认值
- ✅ 特殊变量和引用
- ✅ 常量定义
接下来,我们将深入学习 Perl 运算符。