Skip to content

3.数据类型

龙腾道 edited this page Jan 16, 2023 · 4 revisions

  TOML 像多数配置文件一样,规定了“语法级类型”(syntax typing,即限制并差别对待未加引号书写的原子值,而不是一律当作字符串、再交由应用程序根据约定解读)。这件事利弊参半,无法兼得,无法像“依赖缩进与否”的阵营选择那样容易取舍——很难讲让“非程序员”理解“true"true" 是不一样的”和“true"true" 是一样的”哪个更容易。只能说,规定“语法类型”可以让解析出的值更加明确、一致,而不规定“语法类型”则可以让高频使用的词更加简洁(你不必把 on 写成 "on"true,毕竟从宏观上看,配置文件本身就是一个文本文件)、更容易表示丰富的配置约定。TOML 规范中包含的值类型如下:

  1. 字符串(只能表示有效的 Unicode 字符,这意味着没有收入 Unicode 的字符、半个 UCS-4 等无效的 Unicode 码点都是不能用的)
  2. 整数(要求实现为 64 比特有符号长整数类型,这意味着正零和负零没有区别,取值范围为 −264−1 至 +264−1−1 ①)
  3. 浮点数(要求实现为 IEEE 754 binary64 值,这意味着正零和负零不同,取值范围大致在 ±1.7✕10308 之间,并存在精度丢失问题;TOML 0.5 开始支持非数和正负无穷,不过在此之前正负无穷也可能通过超出范围来得到)
  4. 布尔值
  5. 哈希表(键名是字符串;不保证键名枚举顺序 ①)
  6. 数组(要求子元素数据类型相同;TOML 1.0 开始解除了这一限制)
  7. 坐标日期时刻(0000 年~9999 年;不支持闰秒;TOML 0.3 开始支持时区偏移和小数秒;TOML 0.5 指出,不保证超过 3 位数的小数秒精度 ②)
  8. 各地日期时刻 ③(TOML 0.5 新增;0000 年~9999 年;不支持闰秒;不保证超过 3 位数的小数秒精度 ②)
  9. 各地日期(TOML 0.5 新增;0000 年~9999 年)
  10. 各地时刻(TOML 0.5 新增;不支持闰秒;不保证超过 3 位数的小数秒精度 ②)

  如果您还需要其它数据类型(比如 null ①,但通常是上述底层数据类型的语法糖)甚至文件编码及字符集(TOML 从最开始就限定了只允许 UTF-8 文件),那么您需要在使用最初考虑它可能的解决方式:

  1. 上下游转换程序。例如将 "5h" 初步解析出的字符串转换为进一步需要的时长值,或将其它编码的二进制文件先解析为字符串,再交由常用的 TOML 解析器解析。
  2. 探讨改进规范。这需要一定的时间,而且显然不太可能为 { tagName = "input", value = "abc" } 设计 <input value="abc" /> 这样的语法糖,那 TOML 就变成 XML 了 ④。
  3. 使用改装解析器。这相当于使用一种自己再开发的其它语言格式,而且需要自行实现它的私有解析器。⑤

① @ltd/j-toml 解析器对此提供了可选的试验选项,可解除这些限制。

② @ltd/j-toml 解析器自动解除了这些限制。

③ 注意它的含义不是使用缺省的本地时区偏移量,而是完全不涉及时区偏移问题。

④ 一个罕见的例子是 React 在 JavaScript 中引入了预编译的 JSX,但更常见的还是 Vue 在 template 选项中使用字符串表示其它嵌入语言。

⑤ 目前有一个 tag 提案,建议在 TOML 语法中预留解析器私有拓展功能的位置,以缓解语言的进化压力,避免方言性分化、或统一标准在仓促之间错误进化而难以回退。您可以在 @ltd/j-toml 解释器中尝试这一功能,并为它进入规范提供更多的实践检验。