如何利用Scala的类型系统来维护动态属性集的类型信息

时间:2013-09-26 14:02:23

标签: json mongodb scala

我遇到了一个用例,我需要从txt文件中解析一堆信息。有效载荷的肉是一堆key:value对,在开发时我都不知道。

Wombat
Area: "Northern Alberta"
Tank Level (ft): -3.395
Temperature (C): 19.3
Batt Voltage: 13.09
Last Maintained: 2012-01-01
Secured: "Yes"

正如您所看到的,字符串,数字,日期和布尔值都有可能。还有一个用例需要为用户创建某些属性的规则,例如:

储罐等级超过 n 时,请通知 some.user@someplace.com
当包含“Alberta”的网站 未安全时,请通知 some.user@someplace.com

根据属性的类型,可用的规则类型会有所不同。我可能还需要对数字类型进行某种聚合。无论如何,总而言之,我需要类型信息。那么什么样的数据结构最好?

最初我会选择不同的元组。

val stringAttributes: Array[(String, String)]
val doubleAttributes: Array[(String, Double)]
val dateAttributes: Array[(String, Date)]

现在看来是错的,或者至少是丑陋的。然后我可能会像:

val attributes: Array[(String, Any)]

现在我在很多地方都有模式匹配。另请注意,我正在为Web应用程序和数据库(MongoDB)使用JSON协议。给前端这样的方便是这样的:

{
    site: "Wombat",
    attributes: [
        { "Area": "Northern Alberta" },
        { "Tank Level (ft)": -3.395 },
        { "Temperature (C)": 19.3 }
    ]
}

但是在后端,我是否对这些类型进行编码?我解析原始JSON吗?最后,我正在寻找维护动态属性集的类型信息的最佳方法,同时支持Web客户端和数据库的JSON。

1 个答案:

答案 0 :(得分:0)

+1 @ david的评论。

为什么不使用JSON端到端,派生每个单独规则所需的类型?然后使用单个函数将JSON值转换为正确的类型(当它不匹配时使用默认值或Option。)

然后你可以使用这样的东西在所有解析的对象上运行规则集:

for (object <- parseObjects(); rule <- rules) {
  val value = coerce(object, rule.desiredType)
  rule(value)
}

或类似的东西,例如让规则本身调用强制代码。在您进行规则处理之前,您似乎并不需要对象具有类型,所以为什么要尝试?

P.S。 Typesafe Config可能已经为你解析了文件,虽然它看起来是一种简单的解析格式。