DolphinDB 使用指南第三期|Dlang 脚本写不顺?从这几个细节开始排查

0 阅读4分钟

Dlang 是 DolphinDB 内置的高性能脚本语言,语法简洁、表达力强,既能像 Python 一样快速编写,又能保持接近底层的执行效率,是处理大规模数据的理想选择。

不过,当你真正开始写脚本时,画风可能突然就变了:调用字符串处理函数进行计算,为什么系统抛出异常说类型不正确?两个整数相除,小数怎么说没就没?那个 NULL 和空字符串,到底是不是一回事?还有时间、浮点数、变量清理……每一个看起来都不难,但组合在一起,就是一张“新手劝退体验卡”。

别急,这篇文章就是来帮你把这些“小问题”一个个捋顺的。下面我们从最常见的困惑说起,一条一条解答。

一、选对引号,定准类型

Dlang 里有三种引号:单引号、双引号和反引号,它们的区别其实很简单:

注意,CHAR 类型不能直接放进 SYMBOL 向量里。如果你需要这样做,很简单:先调用 string 函数把它转成 STRING 类型,然后再追加就可以了。

二、除法符号用反了,小数说丢就丢

两个整数用 / 做除法,结果会被取整。想要保留小数部分,换反斜杠 \ 就行。

100 / 3    // 33
100 \ 3    // 33.333...

如果被除数或除数中有一个是浮点数,那么用 / 还是 \ 结果都一样。

说到浮点数,它小数点后多出几位不是 bug,是二进制存储的老毛病。对精度敏感的场景,可以用 round 控制小数位数,或者直接换 DECIMAL 类型。

如果要比较两个浮点数,别用 ==,eqFloat 才是正解。

如果要取整,可以用以下三个函数:

三、空值有三种,别混为一谈

DolphinDB 里的空值怎么表示?看看下面的表格就清楚了。

四、看清变量类型,再决定怎么清理

不确定一个变量是向量、表还是字典?typestr 直接告诉你答案。

symVec = [`a, `b, `c, `d]$SYMBOL
t = table(1 2 3 as id, symVec as symbol, 1 2 3 as value)
d = dict(`a`b`c, 1 2 3)
typestr symVec // FAST SYMBOL VECTOR
typestr t // IN-MEMORY TABLE
typestr d // STRING->INT DICTIONARY

不同类型的变量,清理方式也不一样。下面这张表总结了常见情况的对应操作:

五、时间溢出回绕到1970?该换类型了!

DATETIME 底层是 32 位整数,只能表示 1901 到 2038 年之间的数据。超出这个范围就会溢出,回绕到 1970 年——数据存储的时候,存成 TIMESTAMP 是更好的选择。

时间转换也有对应函数,记这四组基本够用:

六、字符串处理,记住这几个函数

想让字符串输出得整整齐齐,该用什么? stringFormat 可以按指定宽度对齐和填充。

怎么判断一个字符串里是否包含某个词? 用 strpos 或 strFind,它会返回子串的位置索引,找不到就返回 -1。

想从一段文本里提取出想要的内容,有哪些办法? 三种常用方式:正则匹配用 regexFindStr,固定位置用 substr,按分隔符拆用 split。

fileName = "AP210_ZCE_20220701.txt"
regexFindStr(fileName, "[0-9]{8}")  // 输出 '20220701'
substr(fileName, 10, 8)  // 输出 '20220701'
split(fileName, "_").last().split(".").first() // 输出 '20220701'

七、向量筛选,不用写循环

如果你想获取向量中大于某值的元素索引,不需要写循环。先构造索引序列,再用条件过滤,这是 DolphinDB 向量化编程的典型写法。

v = 1 2 3 4 5
at(v>3)   // [3,4]

八、字典转表和删键,两个函数搞定

字典转表格用 transpose,删除指定键用 erase!。

d = dict(`a`b`c, 1 2 3)
transpose(d)      // 转为表格
erase!(d, `a)     // 删除键 a

九、Module 传不上去?多半是路径或缓存问题

仅需三步,即可通过 VSCode 上传 module:

step 1 :VSCode 右上角选择需要上传的 module 文件

step 2 :依次点击“上传”“DolphinDB: 上传模块”

step 3:在弹出的对话框中选择是否加密

上传的 module 找不到?先检查三点:

  • 上传节点和连接节点是否一致
  • 文件名与内部 module 名是否相同
  • 是否放在了 Home 路径下

新的 module 重新上传后,为什么用的还是旧的 module?

  • 检查新的 module 上传的节点和客户端连接的节点是否为同一个
  • module 有缓存,用 clearCachedModules() 清理一下再试
  • 如果用的是 VSCode,断开连接后重连,再重新上传即可

结语

以上就是 Dlang 使用中最容易出问题的几个细节。把这几条理清楚,日常写脚本基本不会再有莫名其妙卡住的地方。当然,每个人的使用习惯不同,遇到的问题也不一样。如果你在 Dlang 使用过程中有其他心得或困惑,欢迎在 ask 社区发帖分享。