Skip to content

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 的变量:

  1. ✅ 变量声明(my、our、local)
  2. ✅ 变量作用域(词法作用域、动态作用域)
  3. ✅ 变量命名规则和约定
  4. ✅ 变量赋值和默认值
  5. ✅ 特殊变量和引用
  6. ✅ 常量定义

接下来,我们将深入学习 Perl 运算符