【问题标题】:Changing an immutable object F#更改不可变对象 F#
【发布时间】:2014-08-18 07:07:43
【问题描述】:

我认为这个标题是错误的,但无法创建一个抽象地反映我想要实现的标题。

我正在编写一个调用服务并将数据作为 JSON 字符串检索的函数。该函数使用JSON type provider 解析字符串。在某些情况下,我想修改该 JSON 对象的属性,然后返回修改后的对象的字符串。因此,如果呼叫的响应是

{"property1" : "value1","property2" : "value2", "property3": "value3" }

我想将 property3 更改为新值,然后返回 JSON 字符串。

如果 JsonProvider 是可变的,这将是一个类似的练习:

type JsonResponse = 
        JsonProvider<""" {"property1" : "value1", 
                          "property2" : "value2",
                          "property3": "value3" } """>

let jsonResponse = JsonResponse.Parse(response)
jsonResponse.Property3 <- "new value"
jsonResponse.ToString()

但是,这不起作用,因为无法设置属性。我正在尝试确定解决此问题的最佳方法。我很高兴根据原始响应初始化一个新对象,但修改了参数,但我不确定是否有简单的方法来实现这一点。

作为参考,JSON 对象比给出的平面示例涉及更多,并且包含更深的层次结构。

【问题讨论】:

  • 如果jsonResponse的类型是一条记录,你可以做{ jsonRespose with Property3 = "new value" }。但这似乎不起作用。
  • 很遗憾,类型提供者目前无法创建记录类型。

标签: json f# type-providers f#-data


【解决方案1】:

是的,您需要创建一个新对象,更改您想要的位并使用现有对象的值来处理其余部分。不久前,我们为 XML 和 JSON 类型提供程序添加了编写 API。你会注意到代表你的 JSON 的类型有构造函数。你可以在this link底部看到一个使用的例子

【讨论】:

  • 感谢您的回答。我已经对此进行了试验,唯一能做到这一点的方法是将 JSON 的所有属性指定为构造函数中的参数。这适用于我给出的示例 let newThing = JsonResponse.Example("value2", "value3", "value3") 但对于大型对象图,这并不实际。您是否有任何见解如何以更“挑剔”的方式做到这一点,即仅将旧对象的特定属性修改为新对象。我想在新对象上设置的属性是层次结构深处的几个层。
  • 写入 API 相对较新,我们添加了完整的构造函数支持,以及从其他 JsonValue 对象复制的能力(底层类型已删除) - 这允许您在 JSON 类型提供程序类型之间复制数据共享嵌套在其中的相同子类型。对于您想要的,它可能需要类型提供程序中的一些新支持。我同意这会很有用,您或许应该为此在 FSharp.Data github 中打开一个问题。 (或者自己去!)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多