Logo
Section 1 / 10

标识符

学习 Perl 语言中标识符/命名约定的基础知识。

导入

标识符

学习 Perl 语言中标识符/命名约定的基础知识。

名称

名称(或 标识符)在 Perl 程序中无处不在。它们主要为我们程序员提供便利;我们为变量、函数、包、类甚至文件句柄选择名称。所有有效的 Perl 名称都以字母或下划线开头,可选地包含任意组合的字母、数字和下划线。当启用 utf8 语法时,我们还可以在标识符中使用任何 #key# UTF-8:UTF-8 是一种常用的 Unicode 字符变长编码方式。它仅用一个字节表示 ASCII 字符。#key# 的词字符。

以下是一些有效的 Perl 标识符:

1my $name; 2my @_private_names; 3my %Names_to_Addresses; 4sub anAwkwardName3;
1use utf8; 2package Ingy::Döt::Net;

以下是一些无效的 Perl 标识符:

1my $invalid name; # 空格无效 2my @3; # 不能以数字开头 3my %~flags; # 符号在名称中无效 4 5package a-lisp-style-name; # 应使用下划线代替

注意: 名称的存在主要是为了方便我们作为程序员。

这些规则仅适用于源代码中出现的字面名称,例如 sub fetch_pie 或 my $waffleiron。

只有 Perl 的解析器强制执行标识符名称的规则。我们也可以通过运行时生成或程序输入提供的名称来引用实体。这些 符号查找 提供了灵活性,但代价是安全性降低。间接调用函数或方法,或在命名空间中查找符号,使我们能够绕过 Perl 的解析器。符号查找可能导致代码难以理解。正如 Mark Jason Dominus 所建议的,我们应该优先使用 #key# 哈希:哈希是一种聚合数据结构,将字符串键与标量值关联起来。#key# 或 #key# 嵌套数据结构:在 Perl 中,通过引用可以实现嵌套数据结构,例如数组的数组或哈希的哈希。#key#,而不是使用像 $recipe1、$recipe2 这样的命名变量。

1my $scalar; 2my @array; 3my %hash;

符号位将变量分为不同的命名空间。虽然可能(尽管令人困惑),可以声明同名但类型不同的多个变量:

1my ($bad_name, @bad_name, %bad_name);

Perl 不会混淆,但人类会。

变体符号位

变量的符号位会根据其使用方式而变化;这被称为 变体符号位。就像上下文决定了我们期望从操作中获取多少项或何种类型的数据一样,符号位决定了我们如何操作变量的数据。例如,我们可以使用标量符号位 $ 来访问数组或哈希中的单个元素:

1 # 从数组或哈希中获取单个值 2my $hash_element = $hash{ $key }; 3my $array_element = $array[ $index ]; 4 5# 设置数组或哈希中的单个值 6$hash{ $key } = 'value'; 7$array[ $index ] = 'item';
1my @hash_elements = @hash{ @keys }; 2my @array_elements = @array[ @indexes ]; 3my %hash; 4 5@hash{ @keys } = @values;

由于 Perl 的变体符号位,判断变量类型(即标量、数组或哈希)最可靠的方法是观察对其执行的操作。数组支持通过方括号进行索引访问。哈希支持通过花括号进行键值访问。标量则不支持这两种方式。

动手实践

让我们在下面的代码沙箱中尝试一些示例:

1# 初始化 2my @array = (11, 13, 15, 17, 19, 21); # 定义一个数组 3my %hash = (a => 'apple', b => 'bat', c => 'cat', d => 'donut'); 4 5# 从数组或哈希中获取单个值 6my $key = 'a'; 7my $hash_element = $hash{ $key }; 8my $index = 4; 9my $array_element = $array[ $index ]; 10 11# 设置数组或哈希中的单个值 12$hash{ $key } = 'value'; 13$array[ $index ] = 'item'; 14 15# 输出 16say "获取和设置单个值后:"; 17say "哈希元素: $hash_element"; 18say "哈希本身: @{[ %hash ]}"; 19say "数组元素: $array_element"; 20say "数组本身: @array"; 21 22 23# 从数组或哈希中获取一组值 24my @keys = ('b', 'd'); 25my @hash_elements = @hash{ @keys }; 26my @indexes = (0, 2, 5); 27my @array_elements = @array[ @indexes ]; 28 29# 设置数组或哈希中的一组值 30@hash{ @keys } = ('bonsai', 'delta'); 31@array[ @indexes ] = (10, 12, 14); 32 33# 输出 34say "\n获取和设置一组值后:"; 35say "哈希元素: @hash_elements"; 36say "哈希本身: @{[ %hash ]}"; 37say "数组元素: @array_elements"; 38say "数组本身: @array";

命名空间

Perl 允许我们将相似的函数和变量组织到各自唯一的命名空间中,即命名空间。命名空间 是一组以全局唯一名称分组的符号。Perl 支持多级命名空间,名称之间用双冒号 :: 连接。DessertShop::IceCream 指代一组相关的变量和函数,例如 scoop() 和 pour_hot_fudge()。

命名空间的特性

在命名空间内部,可以使用成员的简短名称。在命名空间外部,则必须使用完整限定名称。在 DessertShop::IceCream 内部,add_sprinkles() 与外部的 DessertShop::IceCream::add_sprinkles() 指向同一个函数。

包名称遵循标准标识符规则。按照惯例,Perl 核心保留小写字母的包名称用于核心 #key# 语法模块:影响语言行为的 Perl 模块,如 strict 和 warnings。用户自定义的包名称均以大写字母开头。这是一种主要由社区规范所维护的约定。

Perl 中的所有命名空间都是全局可见的。当 Perl 查找 DessertShop::IceCream::Freezer 中的符号时,它会先在 main:: 符号表中查找代表 DessertShop:: 命名空间的符号,然后在该命名空间中查找 IceCream:: 命名空间,依此类推。然而,Freezer:: 从 IceCream:: 命名空间外部也是可见的。前者嵌套于后者之中,仅仅是一种存储机制,并不表示父包与子包或兄弟包之间的任何逻辑关系。

只有我们作为程序员,才能通过选择合适的名称并合理组织,使实体之间的 逻辑 关系变得清晰明了。

Perl 的哲学

变量