2.9. Table¶
Tables are associative containers implemented as a set of key/value pairs:
var tab: table<string; int>
tab["10"] = 10
tab["20"] = 20
tab["some"] = 10
tab["some"] = 20 // replaces the value for 'some' key
List of relevant builtin functions: clear, key_exists, find, erase. for safety, find doesn’t return anything. Instead it works with block as last argument. It can be worked with rbpipe operator
var tab: table<string; int>
tab["some"] = 10
find(tab,"some") <| $(var pValue: int? const)
if pValue != null
assert(deref(pValue) == 10)
It is done so, because otherwise find would have to return pointer to value, which would continue to point ‘somewhere’, even if data is deleted. Consider this hypothetical find and the following example
var tab: table<string; int>
tab["some"] = 10
var v: int? = find(tab,"some")
assert(v) // not null!
tab |> clear()
deref(v) = 10 // where we will write this 10? UB and segfault!
So, if you just want to check for existence of key in table, use key_exists(table, key).
Tables (as well as arrays, structs, and handled types) will be passed to functions by reference only.
Tables can not be assigned, only cloned or moved.
def clone_table(var a, b: table<string, int>)
a := b // a is not deep copy of b
clone(a, b) // same as above
a = b // error
def move_table(var a, b: table<string, int>)
a <- b //a is no points to same data as b, and b is empty.
Table key can be not only string, but any other ‘workhorse’ type as well.
Tables can be constructed inline
let tab <- {{ "one"=>1; "two"=>2 }}
Which is syntax sugar for
let tab : table<string;int> <- to_table_move([[tuple<string;int>[2] "one"=>1; "two"=>2]])