如何将字符串解析为任何F#数据?
在F#中,任何如何将字符串解析为任何F#数据?,f#,f#-data,F#,F# Data,在F#中,任何数据都可以通过函数sprintf进行字符串化,如下所示: type someKindOfDataType = ... let data : someKindOfDataType = ... sprintf "%A" data 我们是否可以使用反转函数将字符串解析回某种类型的数据类型,如下所示: let parse<'someKingOfDataType> (s:string) : someKindOfDataType = .... let parse您描述的是通常称
数据
都可以通过函数sprintf
进行字符串化,如下所示:
type someKindOfDataType = ...
let data : someKindOfDataType = ...
sprintf "%A" data
我们是否可以使用反转函数将字符串解析回某种类型的数据类型,如下所示:
let parse<'someKingOfDataType> (s:string) : someKindOfDataType = ....
let parse您描述的是通常称为序列化的内容——从内存中的数据结构转换为可通过网络传输的表示,可以是XML、JSON、二进制等,反序列化——反之亦然
sprintf“%A”
旨在为数据提供方便的可视化表示,通常仅用于开发目的,而不是用于生产。它实际上并不进行序列化,因为没有反序列化的方法
如果您想将F#数据序列化为字符串,我建议您通过库(如)使用JSON
请注意,这不会产生类似于sprintf“%A”
这样的F#源代码的字符串,因为目的不同。例如:
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|]
let a = Int32.Parse "5"
let b =
match Int32.TryParse "5" with
| true, value -> Some value
| _ -> None
Newtonsoft.Json.JsonConvert.SerializeObject[|约3;无|]
//“[{”大小写“:“某些”,“字段“:[3]},null]””
Newtonsoft.Json.JsonConvert.DeserializeObject“”“[{”大小写“:“一些”,“字段“:[3]},null]”
//[|大约3;没有]
您需要提供要反序列化的类型,如果字符串不表示该类型的有效实例,此操作可能会引发异常。您描述的是通常称为序列化的内容-从内存中的数据结构转换为可通过网络传输的表示,可以是XML、JSON、二进制等,反序列化则相反
sprintf“%A”
旨在为数据提供方便的可视化表示,通常仅用于开发目的,而不是用于生产。它实际上并不进行序列化,因为没有反序列化的方法
如果您想将F#数据序列化为字符串,我建议您通过库(如)使用JSON
请注意,这不会产生类似于sprintf“%A”这样的F#源代码的字符串,因为目的不同。例如:
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|]
let a = Int32.Parse "5"
let b =
match Int32.TryParse "5" with
| true, value -> Some value
| _ -> None
Newtonsoft.Json.JsonConvert.SerializeObject[|约3;无|]
//“[{”大小写“:“某些”,“字段“:[3]},null]””
Newtonsoft.Json.JsonConvert.DeserializeObject“”“[{”大小写“:“一些”,“字段“:[3]},null]”
//[|大约3;没有]
您需要提供要反序列化到的类型,如果字符串不表示该类型的有效实例,此操作可能会引发异常。标准.NET方法是,通常在您尝试解析的类型的类中使用
Parse
或TryParse
方法
但是在F#中,TryParse
函数不是很友好,因为它使用了一个输出参数,F#编译器仍然允许您将其视为一个元组,这使事情变得更好,但您仍然希望得到一个选项,下面是一个示例:
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|]
let a = Int32.Parse "5"
let b =
match Int32.TryParse "5" with
| true, value -> Some value
| _ -> None
如果您想使用一个库,它既有函数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
,它就可以工作。标准的.NET方式是,通常在您试图解析的类型的类中使用Parse
或TryParse
方法
但是在F#中,TryParse
函数不是很友好,因为它使用了一个输出参数,F#编译器仍然允许您将其视为一个元组,这使事情变得更好,但您仍然希望得到一个选项,下面是一个示例:
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|]
let a = Int32.Parse "5"
let b =
match Int32.TryParse "5" with
| true, value -> Some value
| _ -> None
如果您想使用一个库,它既有函数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
,它就可以工作。非常感谢您的回答。很高兴学习你的图书馆和帖子。您在F#+中重载内联函数解析的技术非常有趣和出色。它允许使用返回类型作为签名来选择converter.fs的类型解析器中静态解析函数中实现的解析器。然而,正如您所提到的,每个类型都需要编写其唯一的解析器函数并在类型解析器中定义。这不是我想要的。但再次感谢您的回答。在类型解析器中不一定如此,这仅适用于没有“内置”解析(或最终是TryParse)方法的类型。这里的例子已经有了。关于“如何将字符串解析为类型值并将类型值字符串化”的问题让我想到了Haskell,它的标准功能是允许任何用户定义的派生类型显示、读取、,因此,该类型将自动派生重载的“read”和“print”函数,其工作方式与stringify和parse类似!我爱哈斯克尔。是的,当我回答你的问题时,我也想到了这一点;)非常感谢你的回答。很高兴学习你的图书馆和帖子。您在F#+中重载内联函数解析的技术非常有趣和出色。它允许使用返回类型作为签名来选择converter.fs的类型解析器中静态解析函数中实现的解析器。然而,正如您所提到的,每个类型都需要编写其唯一的解析器函数并在类型解析器中定义。这不是我想要的。但再次感谢您的回答。在类型解析器中不一定如此,这仅适用于没有“内置”解析(或最终是TryParse)方法的类型。这里的例子已经有了。关于“如何将字符串解析为类型值并将类型值字符串化”的问题让我想到了Haskell,它的标准功能是允许任何用户定义的派生类型显示、读取、,因此,该类型将自动派生重载的“read”和“print”函数,其工作方式与stringify和parse类似!我爱哈斯克尔。是的,当我回答时,我也想到了这一点