【发布时间】:2014-10-04 08:36:28
【问题描述】:
我正在 Nim 中制作一个小型 Web 服务,我需要使用 json 响应请求。我正在使用jester module 来提供服务。我希望我可以使用 Nim 基础库中的 json 模块来构造某种具有字段和值的对象,然后将其转换为 json 字符串。但是怎么做?或者有没有更好的方法在 Nim 中构造 json?
【问题讨论】:
我正在 Nim 中制作一个小型 Web 服务,我需要使用 json 响应请求。我正在使用jester module 来提供服务。我希望我可以使用 Nim 基础库中的 json 模块来构造某种具有字段和值的对象,然后将其转换为 json 字符串。但是怎么做?或者有没有更好的方法在 Nim 中构造 json?
【问题讨论】:
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"}
【讨论】:
marshal 模块相当于 Python 中的 pickle,它使用 JSON 作为其序列化格式纯属巧合,请勿使用它将对象序列化为 JSON。这尤其是您现在不应该做的事情,因为 json 模块有效地支持同样的事情:play.nim-lang.org/#ix=2uPe
在 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()
【讨论】:
对于在此线程中找到基于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只是巧合,以后可能会选择不同的格式。
【讨论】:
echo(%p) 对您的数据结构“正常工作”或失败?大概如果您的 Person 类型具有不是 string 或 int 的属性,那么您将不得不做更多的工作 - 什么是惯用的 Nim 方式来处理它?
%p 中的% 是来自json 模块的通用过程吗? nim-lang.org/docs/json.html#%25%2Cstring 这是否意味着您可以实现自己的 % 专业化(这是正确的术语吗?)来处理其他数据类型,例如序列化 DateTime -> string?
echo 在其参数上隐式调用$(请参阅echo 的文档)。 $ 是 Nim 的“toString”函数。因此,只需为您的数据类型实现$,您就可以打印它的字符串表示。 % 返回一个JsonNode,而$ 是为JsonNode 实现的,所以echo %p(或echo $ %p)有效。很简单,真的。 “大概如果您的 Person 类型具有不是字符串或 int 的属性,那么您将不得不做更多的工作” - 当然...... json 模块的实现者完成了这项工作。 (而int 并不特别——$ for int 由 Nim 库提供。)
执行以下操作:
import json
var jsonResponse = %*
{"data": [{ "id": 35,
"type": "car",
"attributes": {"color":"red"} }]}
var body = ""
toUgly(body, jsonResponse)
echo body
【讨论】: