在F#中,按功能data
设置的任何stringify
都可以是sprintf
,如下所示:
type someKindOfDataType = ...
let data : someKindOfDataType = ...
sprintf "%A" data
我们可以使用反转函数将字符串解析回someKindOfDataType
,如下所示:?
let parse<'someKingOfDataType> (s:string) : someKindOfDataType = ....
就像javascript中的JSON.parse一样?
答案 0 :(得分:2)
您正在描述通常被称为序列化的内容 - 从内存数据结构转换为可以通过网络传输的表示形式,可以是XML,JSON,二进制等。 - 和反序列化 - 相反。
sprintf "%A"
旨在提供方便的数据可视化表示,通常仅用于开发目的而非生产中。它实际上并没有进行序列化,因为没有办法反序列化。
如果您想将F#数据序列化为字符串,我建议您通过Newtonsoft.Json等库使用JSON。
请注意,这不会产生类似于F#源代码的字符串,例如sprintf "%A"
,因为目的不同。一个例子:
Newtonsoft.Json.JsonConvert.SerializeObject [|Some 3; None|]
// """[{"Case":"Some","Fields":[3]},null]"""
Newtonsoft.Json.JsonConvert.DeserializeObject<int option []> """[{"Case":"Some","Fields":[3]},null]"""
// [|Some 3; None|]
您需要提供要反序列化的类型,如果字符串不代表该类型的有效实例,则此操作可能会抛出异常。
答案 1 :(得分:1)
标准的.NET方式通常是您在您尝试解析的类型的类中使用Parse
或TryParse
方法。
但是在F#中,TryParse
函数不是很友好,因为它使用输出参数,F#编译器仍允许你将它看作元组,这会使事情变得更好,但你仍然期待得到一个选项,这是一个例子:
let a = Int32.Parse "5"
let b =
match Int32.TryParse "5" with
| true, value -> Some value
| _ -> None
如果你想使用图书馆F#+有两个函数parse
和tryParse
,它们会为你做以上所有事情:
#r @"FSharpPlus.dll"
open FSharpPlus
open System
let (a:int) = parse "5"
let (b:int option) = tryParse "5"
let (c: Net.IPAddress option) = tryParse "10.0.0.1"
// val a : int = 5
// val b : int option = Some 5
// val c : Net.IPAddress option = Some 10.0.0.1
只要类型定义了Parse
或TryParse
,它就会起作用。