Kdb中如何通过引用将表传递给函数
Q语言函数更新全局表的问题与解决方法
一、问题定义
先定义空表myt:
myt:([] id:`int$(); score:`int$())
直接向表中插入记录很简单,示例如下:
`myt upsert `id`score!1 100
但如果要编写通用函数向指定表插入数据,直接传表对象会出现问题。初次尝试的函数代码:
upd:{[t] t upsert `id`score!42 314;} upd[myt]
这种调用只会更新myt的本地副本,原全局表不会被修改。
二、备选方案的局限性
1. 硬编码全局变量
在函数内部直接指定全局表名称:
upd:{`myt upsert `id`score!42 314;} upd[]
这种方式只能操作固定的表,若需要处理myt0、myt1等多个同结构表,就得编写大量重复函数:
upd0:{`myt0 upsert `id`score!42 314;} upd1:{`myt1 upsert `id`score!42 314;} upd2:{`myt2 upsert `id`score!42 314;} ...
显然不符合代码复用的需求。
2. 函数返回新表后外部赋值
移除函数末尾的分号,让函数返回更新后的表,再在外部重新赋值:
upd:{[t] t upsert `id`score!42 314} / 返回插入后的值 myt:upd[myt]
这种方法能生效,但当操作次数达数百万级、表规模持续增大时,性能会逐渐下降。因为该方式放弃了upsert的原地更新特性,每次都会复制整个表,开销随表大小线性增长。
三、最优解决方案:传递表的符号名称
通过传递表的全局名称符号(在表名前加`),即可实现函数内对原全局表的原地更新,完美解决问题:
upd:{[t] t upsert `id`score!42 314;} upd[`myt] / 可以正常修改原全局表
内容的提问来源于stack exchange,提问作者David Wu
相关产品推荐
相关产品推荐

