2.11. Table
表是作为一组键/值对实现的关联容器:
var tab: table<string,int>
unsafe {
tab["10"] = 10
tab["20"] = 20
tab["some"] = 10
tab["some"] = 20 // 替换 'some' 键的值
}
通过 index 运算符访问 table 元素是不安全的,因为在 daslang 容器中存储未装箱的值。 请考虑以下示例:
tab["1"] = tab["2"] // 这可能会打破表格
发生的情况是,如果缺少任何一个键,table 可能会在 tab[“1”] 或 tab[“2”] 之后调整大小(类似于 C++ STL hash_map)。
可以通过 CodeOfPolicies 关闭不安全错误,也可以使用以下选项:
options unsafe_table_lookup = false
表格的安全导航是安全的,因为它不会创建缺失的键:
var tab <- { "one"=>1, "two"=>2 }
let t = tab?["one"] ?? -1 // 这是安全的,因为它不会创建缺失的键
assert(t==1)
它也可以写入:
var tab <- { "one"=>1, "two"=>2 }
var dummy = 0
tab?["one"] ?? dummy = 10 // 如果表中没有 “one”,则 dummy 将设置为 10
有一组安全函数可用于处理表,即使表为空或调整大小,也可以安全地使用这些函数。
有几个相关的内置函数: clear
, key_exists
, get
, 和 erase
.
get
将 block 作为最后一个参数,如果找到 value,则返回。它可以与 rbpipe 运算符一起使用:
let tab <- { "one"=>1, "two"=>2 }
let found = get(tab,"one") <| $(val) {
assert(val==1)
}
assert(found)
也有可用的非常量版本:
var tab <- { "one"=>1, "two"=>2 }
let found = get(tab,"one") <| $(var val) {
val = 123
}
let t = tab |> get_value("one")
assert(t==123)
insert, insert_clone, 和 emplace 是向表格中添加元素的安全方式:
var tab <- { "one"=>1, "two"=>2 }
tab |> insert("three",3) // 插入新的键/值对
tab |> insert_clone("four",4) // 插入新的键/值对,但克隆值
var five = 5
tab |> emplace("five",five) // 插入新的键/值对,但移动值
表(以及数组、结构和处理类型)仅通过引用传递给函数。
无法分配表,只能克隆或移动表。
def clone_table(var a, b: table<string, int>) {
a := b // a 不是 b 的深拷贝
clone(a, b) // 同上
a = b // 错误
}
def move_table(var a, b: table<string, int>) {
a <- b //a 不指向与 b 相同的数据,B 为空。
}
Table Keys 不仅可以是字符串,也可以是任何其他 ‘workhorse’ 类型。
可以内联构造表:
let tab <- { "one"=>1, "two"=>2 }
这是语法糖:
let tab : table<string,int> <- to_table_move(fixed_array<tuple<string,int>>(("one",1),("two",2)))
替代语法为:
let tab <- table("one"=>1, "two"=>2)
let tab <- table<string,int>("one"=>1, "two"=>2)
也可以声明不包含关联数据的 Table:
var tab : table<int>
tab |> insert(1) // 这就是我们如何将键插入这样的 table
Table 可以使用 for
循环进行迭代:
var tab <- { "one"=>1, "two"=>2 }
for ( key, value in keys(tab), values(tab) ) {
print("key: {key}, value: {value}\n")
}
不包含关联数据的 Table 只有键。