Solaris 动态跟踪指南

关联数组

关联数组用于表示数据元素的集合,可通过指定一个称为的名称来检索这些数据元素。D 关联数组的键由称为元组的标量表达式值的列表构成。您可以将数组元组本身视为函数的假想参数列表,在引用该数组时系统将调用该函数来检索相应的数组值。每个 D 关联数组都有一个固定的键签名,该签名由固定数量的元组元素组成,其中每个元素具有给定的固定类型。可以在 D 程序为每个数组定义不同的键签名。

关联数组与大小固定的常规数组不同,因为关联数组对元素的数量没有预定义的限制。关联数组的元素可以通过任何元组建立索引,而不是仅使用整数作为键,这些元素并不存储在预先分配的连续存储位置中。在 C、C++ 或 JavaTM 语言程序中要使用散列表或其他简单字典数据结构的情况下,使用关联数组会很有用。使用关联数组可以为 D 程序中捕获的事件和状态创建动态历史记录,使用该历史记录可创建更复杂的控制流。

要定义关联数组,请编写以下形式的赋值表达式:

name [ key ] = expression ;

其中,name 是任何有效的 D 标识符,key 是逗号分隔的一个或多个表达式的列表。例如,以下语句使用键签名 [ int, string ] 定义关联数组 a,并将整数值 456 存储在由元组 [ 123, "hello" ] 命名的位置中:

a[123, "hello"] = 456;

对于给定数组中的所有元素,数组中包含的每个对象的类型也是固定的。由于已对 a 指定了整数 456,所以该数组中存储的每个后续值也将为 int 类型。可以使用第 2 章中定义的任何赋值运算符,根据为每个运算符定义的操作数规则来修改关联数组元素。如果尝试进行不兼容的赋值,D 编译器将产生相应的错误消息。您可以将对标量变量使用的任何类型用于关联数组键或值。但不能将关联数组作为键或值嵌套在另一个关联数组中。

您可以使用与数组键签名兼容的任何元组引用关联数组。元组兼容性规则与函数调用和变量赋值的规则相似:元组的长度必须相同,且实际参数列表中的每种类型必须与正式键签名中的相应类型兼容。例如,如果按照如下所示定义关联数组 x

x[123ull] = 0;

则键签名为 unsigned long long 类型,值为 int 类型。也可使用表达式 x['a'] 引用该数组,因为根据类型转换中说明的算术转换规则,由 int 类型的字符常量 'a' 组成且长度为 1 的元组与键签名 unsigned long long 兼容。

如果需要在使用 D 关联数组前对其进行显式声明,可以在程序源代码中探测子句外部创建数组名称和键签名的声明:

int x[unsigned long long, char];

BEGIN
{
	x[123ull, 'a'] = 456;
}

定义关联数组后,将允许引用兼容键签名的任何元组,即使先前未对要引用的元组赋值。访问未赋值的关联数组元素定义为返回使用零填充的对象。此定义的后果是,在对关联数组元素赋非零值之前,将不会为该元素分配基础存储空间。相反,对关联数组元素赋值零将会导致 DTrace 解除分配基础存储空间。此行为很重要,因为可对关联数组元素分配的外部动态变量空间是有限的。如果在尝试分配时该空间已用完,分配将会失败,并生成一条错误消息,指示将进行动态变量删除。不再使用的关联数组元素将赋值零。有关消除动态变量删除的其他方法,请参见第 16 章