MudOS 提供了一种叫做 mapping 的数据类型,mapping
是和其他语言(例如Perl)中的联合数组等价的。联合数组与
标准的数组的分别在于,联合数组可以用任意的数据类型来
建立索引(如 string、object、int、array 等等)而不是仅
仅用整数。另外,联合数组是一种“稀疏”的数组,因为一
个 mapping 可以给第 1,000,000 个元素赋值而不给其他所
有的元素赋值。mapping 有两个独特的好用处:
1、数据库
2、代替“struct”类型
一个 mapping 是这样声明的:
mapping x;
一个 mapping 可以这样来初始化:
x = ([ key0 : value0, key1 : value1, ... ]);
(注意:“x = ([]);”可用于创建一个空的 mapping)
注意,一个 mapping必须在你给它分配任何元素之前初始化,
这个限制是因为 MudOS将所有的变量(无论什么类型)都初始
化为 0,如果你不预先初始化一个 mapping,当你尝试给这
个 mapping 分配元素时,你将看到“Indexing on illegal
type”这样的出错信息。
新的 (key, value) 对照可以这样加入 mapping 中:
x[key] = value;
上面这种方式使得 driver 为了指定的键,去寻找一个叫做
“x”的 mapping,如果这个 mapping 里面已经有了这个键,
那么 mapping 中这个键对应的值就被替换为等号右边的值。
如果 mapping 中还没有这个值, 一块额外的空间将被自动
(动态的)分配出来,然后这个 (key, value) 的对照将被插
入这个 mapping 中。
一个映射中的元素可以像下面这样来引用:
write(x[key] + "\n");
一个映射中的元素可以像下面这样来删除:
map_delete(x, key);
这种删除的方式将会导致下面的表达式返回真(1):
undefinedp(x[key])
因此你可以像这样写段程序:
if (undefinedp(value = x["MudOS"]))
{
write("“MudOS”并未在映射“x”中用作一个"
"键。\n");
} else
{
write("“MudOS”键的值是:" + value + "。"
"\n");
}
映射中键(索引)的列表可以用 keys() efun 来获得, 比如
说:
mixed *idx;
mapping x;
x = ([ "x" : 3, "y" : 4]);
idx = keys(x);
idx == ({ "x", "y" }) 或 ({ "y", "x" })。
注意,key() 返回的索引列表是明显用一个随机的顺序排列
的(这个顺序是储存 mapping 的一个副作用)。
映射中值(value)的列表可以用 values() efun 来获得,比
如说:
idx = values(x);
这样 idx 将会等于 ({ 3, 4 }) 或 ({ 4, 3 })。
注意,values() 返回的值的顺序是与 keys()返回的键的顺
序一致的。
映射中(key, value)的对照可以用 each() efun一次次的传
回, 当到达了映射的结尾时,each() 会返回一个空的向量
(0, 0)。each() 返回的顺序是和 key()、values() 的顺序
一致的。例如:
mixed *pair;
while ((pair = each(x)) != ({ }))
{
write("key = " + pair[0] + "\n");
write("value = " + pair[1] + "\n");
}
(注:MudOS v22 中 each() 函数已经被去掉)。
映射可以是二维的(如果有必要,也可以是多维的),就和数
组一样。
mapping x, y;
x = ([ ]);
y = ([ ]);
y["a"] = "c";
x["b"] = y;
结果 x["b"]["a"] == "c"
映射也可以使用“*”运算符:
mapping r1, r2, a;
r1 = ([ ]);
r2 = ([ ]);
r1["driver"] = "mudlib";
r2["mudlib"] = "castle";
因此:
a = r1 * r2
使 a 变成这样一个映射:a["driver"] == "castle";
你也可以把两个映射加起来,两个映射的和就是把它们联合
起来。
a = r1 + r2
这样 a 变成了:
a["driver"] == "mudlib" 而且 a["mudlib"] == "castle"
+= 运算符也是支持的,因此你可以这样用:
a += ([ key : value ]);
可以替代:
a[key] = value;
可是,后面的方法会有效率得多,因为前面的要先创建一个
新的映射,再把它们俩加起来,而后面的不必。
映射中减运算符应该并没有定义,你可以用 map_delete()。
sizeof() 这个 efun 可以用于测定这个 mapping 中一共有
多少对(key, value)对照。
write("映射“x”包括" + sizeof(x) + "个元素"
"。\n");
执行方式:
MudOS 的 mapping是使用一个可扩展的哈希表来实现的,这
个哈希表的容量通常是两倍的,就是说当此哈希表的使用率
趋近于满的时候,哈希表的容量将被扩展为原先的两倍,以
保证它存取的效率。
制作者:
MudOS 的 mapping类型最初由 Whiplash@TMI 完成,一部分
的内容在后来由 Truilkan@TMI重写过(为了使用一个可扩展
哈希表来代替 2 杈树)。
实现 mapping 的一部分数据结构是基于 Larry Wall的Perl
语言中的 hash.c 模块。Perl 程序包是由 GNU Copyleft的
GPL(General Public License)保护的。
翻译使用的词汇:
associative :联合
key :键
dynamically :动态
mapping :映射
implementation :执行