【问题标题】:How do I leverage Scala's type system to maintain type information for a dynamic set of attributes如何利用 Scala 的类型系统来维护动态属性集的类型信息
【发布时间】:2013-09-27 04:20:36
【问题描述】:

我遇到了一个用例,我需要从 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"

如您所见,字符串、数字、日期和布尔值都有潜力。还有一个用例,用户需要为某些属性创建规则,例如:

Tank Level超过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。

【问题讨论】:

  • 听起来您想要端到端的 JSON,那么为什么不使用诸如 JObjectJField 之类的 lift-json 类型来表示服务器代码中的数据呢?然后你的主要任务将是解析传入的文本文件。
  • 最终,对于每种类型的事物,您将比单独的集合做得更好,因为直到运行时您才知道类型。有一些很酷的东西,比如 shapeless 的 HList,它可以让你构建和操作异构类型的元素,但由于大多数类型信息在运行时被删除,我认为你不能从这些中获得太多好处。
  • 您需要类似异构地图的东西。这个问题可能是相关的:stackoverflow.com/questions/17684023/…

标签: json mongodb scala


【解决方案1】:

对@david 的评论+1。

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

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

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

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

附: Typesafe Config 可能已经能够为您解析文件,尽管它看起来是一种简单的解析格式。

【讨论】:

    猜你喜欢
    • 2017-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多