Skip to content

Perl 数据类型

概述

Perl 是一种弱类型语言,但有三种主要的数据类型:

  1. 标量(Scalars):存储单个值
  2. 数组(Arrays):存储有序的值列表
  3. 哈希(Hashes):存储键值对

每种数据类型都有自己独特的符号前缀:

  • 标量:$
  • 数组:@
  • 哈希:%

标量(Scalars)

标量的值类型

标量可以存储以下类型的值:

perl
use strict;
use warnings;

# 数字
my $integer = 42;          # 整数
my $float = 3.14;          # 浮点数
my $scientific = 1.23e-4;  # 科学计数法

# 字符串
my $string1 = "Hello";     # 双引号字符串
my $string2 = 'World';     # 单引号字符串
my $empty = "";            # 空字符串

# 特殊值
my $undef = undef;         # 未定义值
my $true = 1;              # 真值
my $false = 0;             # 假值

# 引用
my $array_ref = [1, 2, 3];       # 数组引用
my $hash_ref = {a => 1, b => 2}; # 哈希引用

双引号和单引号的区别

perl
my $name = "Alice";

# 双引号:会解析变量和转义字符
print "Hello, $name\n";      # 输出:Hello, Alice
print "Tab\tNewline\n";      # 输出:Tab    Newline

# 单引号:字面量,不解析变量和转义字符
print 'Hello, $name\n';      # 输出:Hello, $name\n
print 'Tab\tNewline\n';      # 输出:Tab\tNewline\n

字符串操作

perl
# 字符串连接
my $first = "Hello";
my $second = "World";
my $combined = $first . " " . $second;  # 使用点运算符
print $combined;  # 输出:Hello World

# 字符串重复
my $dashes = "-" x 10;
print $dashes;    # 输出:----------

# 字符串长度
my $str = "Hello";
my $length = length($str);
print "Length: $length\n";  # 输出:Length: 5

# 子字符串
my $substring = substr($str, 1, 3);  # 从位置1开始,取3个字符
print $substring;  # 输出:ell

# 大小写转换
print uc($str);    # 输出:HELLO
print lc($str);    # 输出:hello
print ucfirst($str); # 输出:Hello(首字母大写)

数组(Arrays)

创建数组

perl
# 空数组
my @empty = ();

# 列表创建
my @numbers = (1, 2, 3, 4, 5);
my @fruits = ("apple", "banana", "orange");

# 使用 qw 简化
my @colors = qw(red green blue yellow);
my @days = qw(Monday Tuesday Wednesday Thursday Friday Saturday Sunday);

# 使用范围
my @range1 = (1..10);       # 1 到 10
my @range2 = ('a'..'z');    # a 到 z
my @range3 = (1..5, 10..15); # 混合范围

访问数组元素

perl
my @numbers = (10, 20, 30, 40, 50);

# 访问单个元素(使用 $ 前缀)
print $numbers[0];  # 输出:10
print $numbers[2];  # 输出:30
print $numbers[-1]; # 输出:50(最后一个元素)

# 访问多个元素(切片)
my @subset = @numbers[1, 3];   # (20, 40)
my @slice = @numbers[0..2];    # (10, 20, 30)

数组操作

perl
my @numbers = (1, 2, 3);

# 添加元素
push @numbers, 4;              # 在末尾添加:(1, 2, 3, 4)
unshift @numbers, 0;           # 在开头添加:(0, 1, 2, 3, 4)

# 移除元素
my $last = pop @numbers;       # 移除并返回最后一个元素:(0, 1, 2, 3)
my $first = shift @numbers;    # 移除并返回第一个元素:(1, 2, 3)

# 数组长度
my $count = scalar @numbers;   # 返回 3
print $#numbers;               # 返回最后一个索引:2

# 删除元素
delete $numbers[1];            # 删除索引 1,但保留位置:(1, undef, 3)
splice @numbers, 1, 1;         # 删除索引 1,不保留位置:(1, 3)

# 排序
my @sorted = sort @numbers;    # 字母排序
my @numeric_sorted = sort { $a <=> $b } @numbers;  # 数字排序

# 反转
my @reversed = reverse @numbers;  # (3, 2, 1)

数组遍历

perl
my @fruits = ("apple", "banana", "orange");

# 使用 foreach
foreach my $fruit (@fruits) {
    print "I like $fruit\n";
}

# 使用 for 循环
for (my $i = 0; $i < @fruits; $i++) {
    print "$fruits[$i]\n";
}

# 使用索引
for my $index (0..$#fruits) {
    print "Index $index: $fruits[$index]\n";
}

数组和标量的转换

perl
# 数组转换为标量(获取长度)
my @array = (1, 2, 3, 4, 5);
my $count = @array;   # $count = 5

# 标量列表转换为数组
my ($a, $b, $c) = (1, 2, 3);

# 数组展开
my @array1 = (1, 2, 3);
my @array2 = (4, 5, 6);
my @combined = (@array1, @array2);  # (1, 2, 3, 4, 5, 6)

# 数组赋值给标量(返回元素个数)
my $num = @array1;  # $num = 3

哈希(Hashes)

创建哈希

perl
# 空哈希
my %empty = ();

# 列表创建(键值对)
my %person = (
    name => "Alice",
    age => 25,
    city => "New York"
);

# 使用逗号
my %scores = (
    "math", 90,
    "english", 85,
    "science", 92
);

# 混合方式
my %data = (
    "name" => "Bob",
    age => 30,
    "city" => "London"
);

访问哈希元素

perl
my %person = (name => "Alice", age => 25);

# 访问单个值(使用 $ 前缀)
print $person{name};     # 输出:Alice
print $person{age};      # 输出:25

# 修改值
$person{age} = 26;

# 访问不存在的键返回 undef
print $person{city};     # 输出:(空或警告)

哈希操作

perl
my %person = (name => "Alice", age => 25, city => "New York");

# 获取所有键
my @keys = keys %person;           # (name, age, city)
my @sorted_keys = sort keys %person;  # 排序后的键

# 获取所有值
my @values = values %person;       # (Alice, 25, New York)

# 获取键值对
my @pairs = %person;               # 展开为列表
while (my ($key, $value) = each %person) {
    print "$key: $value\n";
}

# 检查键是否存在
if (exists $person{name}) {
    print "Name exists\n";
}

# 删除键值对
delete $person{age};

# 哈希长度
my $count = keys %person;  # 返回键的数量

# 清空哈希
%person = ();

哈希遍历

perl
my %scores = (math => 90, english => 85, science => 92);

# 遍历键
foreach my $subject (keys %scores) {
    print "$subject: $scores{$subject}\n";
}

# 遍历值
foreach my $score (values %scores) {
    print "Score: $score\n";
}

# 遍历键值对
while (my ($subject, $score) = each %scores) {
    print "$subject: $score\n";
}

数据类型转换

自动转换

Perl 会自动在数值和字符串之间转换:

perl
# 数值到字符串
my $num = 42;
my $str = "Number: " . $num;   # "Number: 42"

# 字符串到数值
my $string = "123";
my $value = $string + 10;       # 133

# 非数字字符串转换为 0
my $text = "abc";
my $result = $text + 5;         # 5

强制转换

perl
# 强制转换为数值
my $str = "123abc";
my $num = int($str);        # 123
my $float = 0 + $str;       # 123

# 强制转换为字符串
my $number = 456;
my $text = "" . $number;    # "456"
my $text2 = "$number";      # "456"

特殊变量

默认变量 $_

perl
# $_ 是默认输入和模式搜索变量
$_ = "Hello World";
print;          # 打印 $_

# 在循环中自动设置
foreach (1..5) {
    print;       # 打印 $_
}

# grep 和 map 使用 $_
my @numbers = (1, 2, 3, 4, 5);
my @evens = grep { $_ % 2 == 0 } @numbers;  # (2, 4)
my @squared = map { $_ * $_ } @numbers;     # (1, 4, 9, 16, 25)

实践示例

示例 1:购物清单

perl
#!/usr/bin/perl
use strict;
use warnings;

my @shopping_list = qw(apple banana milk bread);
my %prices = (
    apple => 2.5,
    banana => 1.8,
    milk => 3.2,
    bread => 4.0
);

print "=== 购物清单 ===\n";
foreach my $item (@shopping_list) {
    my $price = $prices{$item} || "N/A";
    printf "%-10s: \$%.2f\n", $item, $price;
}

示例 2:学生成绩统计

perl
#!/usr/bin/perl
use strict;
use warnings;

my %students = (
    Alice => { math => 90, english => 85, science => 92 },
    Bob => { math => 78, english => 92, science => 88 },
    Charlie => { math => 95, english => 89, science => 97 }
);

foreach my $name (keys %students) {
    my $scores = $students{$name};
    my $sum = $scores->{math} + $scores->{english} + $scores->{science};
    my $average = $sum / 3;
    printf "%-10s: Math=%d, English=%d, Science=%d, Average=%.1f\n",
           $name, $scores->{math}, $scores->{english},
           $scores->{science}, $average;
}

小结

本章节学习了 Perl 的数据类型:

  1. ✅ 标量:单个值(数字、字符串、引用)
  2. ✅ 数组:有序的值列表
  3. ✅ 哈希:键值对集合
  4. ✅ 数据类型转换
  5. ✅ 特殊变量

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