Perl 数据类型
概述
Perl 是一种弱类型语言,但有三种主要的数据类型:
- 标量(Scalars):存储单个值
- 数组(Arrays):存储有序的值列表
- 哈希(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 的数据类型:
- ✅ 标量:单个值(数字、字符串、引用)
- ✅ 数组:有序的值列表
- ✅ 哈希:键值对集合
- ✅ 数据类型转换
- ✅ 特殊变量