如何将字符串解析为任何 F# 数据?
How to parse string to any F# data?
在 F# 中,任何 data
都可以通过函数 sprintf
stringify
,如下所示:
type someKindOfDataType = ...
let data : someKindOfDataType = ...
sprintf "%A" data
我们能否有一个反转函数来将字符串解析回 someKindOfDataType
,如下所示:?
let parse<'someKingOfDataType> (s:string) : someKindOfDataType = ....
就像 javascript 中的 JSON.parse?
您描述的是通常所说的 序列化 - 从内存中的数据结构转换为可以通过网络传输的表示形式,这可能是 XML、JSON、二进制等 - 和 反序列化 - 相反。
sprintf "%A"
旨在提供方便的数据可视化表示,通常仅用于开发而非生产目的。它实际上并不进行序列化,因为没有办法反序列化。
如果您想将 F# 数据序列化为字符串,我建议通过 Newtonsoft.Json.
等库使用 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|]
您需要提供要反序列化的类型,如果字符串不代表该类型的有效实例,此操作可能会引发异常。
标准的 .NET 方法通常是在您尝试解析的类型的 class 中使用 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
,它就可以工作。
在 F# 中,任何 data
都可以通过函数 sprintf
stringify
,如下所示:
type someKindOfDataType = ...
let data : someKindOfDataType = ...
sprintf "%A" data
我们能否有一个反转函数来将字符串解析回 someKindOfDataType
,如下所示:?
let parse<'someKingOfDataType> (s:string) : someKindOfDataType = ....
就像 javascript 中的 JSON.parse?
您描述的是通常所说的 序列化 - 从内存中的数据结构转换为可以通过网络传输的表示形式,这可能是 XML、JSON、二进制等 - 和 反序列化 - 相反。
sprintf "%A"
旨在提供方便的数据可视化表示,通常仅用于开发而非生产目的。它实际上并不进行序列化,因为没有办法反序列化。
如果您想将 F# 数据序列化为字符串,我建议通过 Newtonsoft.Json.
等库使用 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|]
您需要提供要反序列化的类型,如果字符串不代表该类型的有效实例,此操作可能会引发异常。
标准的 .NET 方法通常是在您尝试解析的类型的 class 中使用 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
,它就可以工作。