Swift JSON 函数调用中的 Vapor 框架差异

Swift Vapor framework difference in JSON function calls

我的问题是 Vapor JSON 函数调用 return JSON(["foo":"bar"])return try JSON(node: ["foo":"bar"]) 有什么区别?

两种变体都有效,正确的方法是什么?

return JSON(node: ["foo":"bar"])return try JSON(["foo":"bar"]) 那样混合它们会使构建失败。

import Vapor

let drop = Droplet()

drop.get("json") { req in
  return JSON(["foo": "bar"])
}

drop.run()

我想我可以回答这个问题。乍一看,它们看起来很相似,但它们非常不同。在这两个初始化程序中一切都返回的唯一原因是...... GENERICS。

没有外部参数

没有外部 arg 初始值设定项引用上面的 JSON(["foo": "bar"])。我们将这些用于 非失败 初始化器,用于可以直接在 JSON 中表示的类型。例如,[String: JSON]String[JSON]Number(Int, UInt, Double) 等。

你可能会说,“等一下,我在上面超过了 [String: String]。好吧,事情是这样的......实际上我们不是。JSON 是 ExpressibleAsStringLiteral所以上面的 ["foo": "bar"] 实际上变成了 ["foo": JSON("bar")] 并允许我们使用无参数初始化器。

带外部参数node:

我们使用外部参数来帮助编译器消除歧义,因为我们无法对可失败和不可失败的初始化程序使用相同的外部参数。

如果您查看 node: 初始值设定项,它是一组通用重载,可让我们简化操作。上面我们提到我们可以直接传递["foo": "bar"],因为它转换为[String: JSON]。好吧,如果我们有一个具体的类型 [String: String] 并且我们尝试使用 JSON(stringDict) 它将失败。但是,如果我们使用 try JSON(node: stringDict),我们可以使用泛型来知道 StringNodeRepresentible,并且我们有足够的上下文将其正确转换为 JSON。或者至少尝试一下!

通过 node: 初始化器,我们可以允许多个不同的泛型变体并使用多个不同的类型。

:)

希望这能解决一些问题,这是代码库中一个非常细微的区域,很乐意详细说明。