【问题标题】:How to convert object to json in Nim如何在 Nim 中将对象转换为 json
【发布时间】:2014-10-04 08:36:28
【问题描述】:

我正在 Nim 中制作一个小型 Web 服务,我需要使用 json 响应请求。我正在使用jester module 来提供服务。我希望我可以使用 Nim 基础库中的 json 模块来构造某种具有字段和值的对象,然后将其转换为 json 字符串。但是怎么做?或者有没有更好的方法在 Nim 中构造 json?

【问题讨论】:

    标签: json nim-lang


    【解决方案1】:

    marshal 模块包括适用于任何类型的通用 object-to-json 序列化算法(目前,它使用运行时类型自省)。

    import marshal
    
    type
      Person = object
        age: int
        name: string
    
    var p = Person(age: 38, name: "Torbjørn")
    
    echo($$p)
    

    输出将是:

    {"age": 38, "name": "Torbj\u00F8rn"}
    

    【讨论】:

    • 虽然 Grzegorz 的答案正是我想要的,但这个答案也比使用 json 模块非常有用、有趣且简单。酷!
    • 似乎在 Nim 中每个人都制作运算符?
    • 不是您应该如何在 Nim 中序列化为 JSON。 marshal 模块相当于 Python 中的 pickle,它使用 JSON 作为其序列化格式纯属巧合,请勿使用它将对象序列化为 JSON。这尤其是您现在不应该做的事情,因为 json 模块有效地支持同样的事情:play.nim-lang.org/#ix=2uPe
    【解决方案2】:

    在 Nim 中,您使用 json module 创建 JsonNode 对象,它们是 object variants。这些可以使用newJObject() 等单独的过程构建,然后填充fields 序列。另一种更快的方法是使用%() proc,它接受一个元组序列,其中一个值是带有 json 字段的字符串,另一个是单独的 JsonNode

    这是一个显示两种方式的示例:

    import json
    
    type
      Person = object ## Our generic person record.
        age: int ## The age of the person.
        name: string ## The name of the person.
    
    proc `%`(p: Person): JsonNode =
      ## Quick wrapper around the generic JObject constructor.
      result = %[("age", %p.age), ("name", %p.name)]
    
    proc myCustomJson(p: Person): JsonNode =
      ## Custom method where we replicate manual construction.
      result = newJObject()
      # Initialize empty sequence with expected field tuples.
      var s: seq[tuple[key: string, val: JsonNode]] = @[]
      # Add the integer field tuple to the sequence of values.
      s.add(("age", newJInt(p.age)))
      # Add the string field tuple to the sequence of values.
      s.add(("name", newJString(p.name)))
      result.fields = s
    
    proc test() =
      # Tests making some jsons.
      var p: Person
      p.age = 24
      p.name = "Minah"
      echo(%p) # { "age": 24,  "name": "Minah"}
      p.age = 33
      p.name = "Sojin"
      echo(%p) # { "age": 33,  "name": "Sojin"}
      p.age = 40
      p.name = "Britney"
      echo p.myCustomJson # { "age": 40,  "name": "Britney"}
    
    when isMainModule: test()
    

    【讨论】:

    • 抱歉,生成 JSON 的方式很糟糕,现在没有人通过手动编写序列化函数来生成它
    • 请查看forum.nim-lang.org/t/6707关于这个错误答案的讨论。
    【解决方案3】:

    对于在此线程中找到基于marshal 的答案的任何人。改用这个:

    import json
    
    type
      Person = object
        age: int
        name: string
    
    var p = Person(age: 38, name: "Torbjørn")
    echo(%p)
    

    请注意,您不应为此使用marshal,它相当于Python 中的pickle 模块,它可能会生成包含您可能不想要的额外数据的JSON。还有,现在生成JSON只是巧合,以后可能会选择不同的格式。

    【讨论】:

    • 作为一个 Nim 新手...这是怎么回事?在什么情况下echo(%p) 对您的数据结构“正常工作”或失败?大概如果您的 Person 类型具有不是 stringint 的属性,那么您将不得不做更多的工作 - 什么是惯用的 Nim 方式来处理它?
    • 所以%p 中的% 是来自json 模块的通用过程吗? nim-lang.org/docs/json.html#%25%2Cstring 这是否意味着您可以实现自己的 % 专业化(这是正确的术语吗?)来处理其他数据类型,例如序列化 DateTime -> string
    • 好吧,我刚试了一下,效果确实不错play.nim-lang.org/#ix=2uPX ...这很好?
    • @Anentropic echo 在其参数上隐式调用$(请参阅echo 的文档)。 $ 是 Nim 的“toString”函数。因此,只需为您的数据类型实现$,您就可以打印它的字符串表示。 % 返回一个JsonNode,而$ 是为JsonNode 实现的,所以echo %p(或echo $ %p)有效。很简单,真的。 “大概如果您的 Person 类型具有不是字符串或 int 的属性,那么您将不得不做更多的工作” - 当然...... json 模块的实现者完成了这项工作。 (而int 并不特别——$ for int 由 Nim 库提供。)
    • @JimBalter 我们同意
    【解决方案4】:

    执行以下操作:

    import json
    
    var jsonResponse = %*
                       {"data": [{ "id": 35,
                                   "type": "car",
                                   "attributes": {"color":"red"} }]}
    
    var body = ""
    
    toUgly(body, jsonResponse)
    
    echo body
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-29
      • 2018-05-24
      • 2021-05-07
      • 1970-01-01
      • 2023-03-17
      • 2017-06-16
      • 2021-11-23
      相关资源
      最近更新 更多