将 Java/JSON 映射解码为 F# 对象涉及两个主要过程:
F# 作为 .NET 语言,可以利用 .NET 生态中的 JSON 处理库,同时也有 F# 特有的方式来处理这种转换。
open System.Text.Json
// 定义 F# 记录类型
type Person = {
Name: string
Age: int
Email: string option
}
// JSON 字符串
let json = """{"Name":"John Doe","Age":30,"Email":"john@example.com"}"""
// 反序列化
let person = JsonSerializer.Deserialize<Person>(json)
printfn "Name: %s, Age: %d, Email: %A" person.Name person.Age person.Email
open Newtonsoft.Json
type Product = {
Id: int
Name: string
Price: decimal
Tags: string list
}
let json = """{"Id":1,"Name":"Laptop","Price":999.99,"Tags":["electronics","computer"]}"""
let product = JsonConvert.DeserializeObject<Product>(json)
printfn "Product: %s ($%.2f)" product.Name product.Price
open FSharp.Data
type UserProvider = JsonProvider<""" {"name":"","age":0,"active":false} """>
let json = """{"name":"Alice","age":25,"active":true}"""
let user = UserProvider.Parse(json)
printfn "User: %s, Age: %d, Active: %b" user.Name user.Age user.Active
type Address = {
Street: string
City: string
ZipCode: string
}
type Customer = {
Id: int
Name: string
Address: Address
}
let json = """
{
"Id": 101,
"Name": "Bob Smith",
"Address": {
"Street": "123 Main St",
"City": "Anytown",
"ZipCode": "12345"
}
}
"""
let customer = JsonSerializer.Deserialize<Customer>(json)
type OrderItem = {
ProductId: int
Quantity: int
UnitPrice: decimal
}
type Order = {
OrderId: int
Items: OrderItem list
Total: decimal
}
let json = """
{
"OrderId": 1001,
"Items": [
{"ProductId": 1, "Quantity": 2, "UnitPrice": 10.99},
{"ProductId": 2, "Quantity": 1, "UnitPrice": 24.99}
],
"Total": 46.97
}
"""
let order = JsonSerializer.Deserialize<Order>(json)
使用 JsonPropertyName
特性:
type Employee = {
[<JsonPropertyName("employee_id")>]
Id: int
[<JsonPropertyName("full_name")>]
Name: string
}
使用 F# 的 option
类型:
type Profile = {
Username: string
Bio: string option
Website: string option
}
let json1 = """{"Username":"user1","Bio":"Developer","Website":"example.com"}"""
let json2 = """{"Username":"user2"}"""
let profile1 = JsonSerializer.Deserialize<Profile>(json1)
let profile2 = JsonSerializer.Deserialize<Profile>(json2)
type Event = {
Name: string
[<JsonConverter(typeof<System.Text.Json.Serialization.JsonStringDateTimeConverter>)>]
Date: System.DateTime
}
type ColorConverter() =
inherit JsonConverter<string>()
override _.Read(reader, _, _) =
let json = reader.GetString()
match json with
| "red" -> "FF0000"
| "green" -> "00FF00"
| "blue" -> "0000FF"
| hex when hex.StartsWith("#") -> hex.Substring(1)
| _ -> json
override _.Write(writer, value, _) =
writer.WriteStringValue(value)
type Widget = {
Name: string
[<JsonConverter(typeof<ColorConverter>)>]
Color: string
}
JsonSerializerOptions
:let options = JsonSerializerOptions()
options.PropertyNameCaseInsensitive <- true
options.Converters.Add(JsonFSharpConverter())
// 重用这个 options 实例
let deserialize<'T> json = JsonSerializer.Deserialize<'T>(json, options)
Utf8JsonReader
进行流式处理:let parseLargeJson (jsonBytes: byte[]) =
let reader = Utf8JsonReader(jsonBytes)
while reader.Read() do
match reader.TokenType with
| JsonTokenType.PropertyName -> printfn "Property: %s" (reader.GetString())
| JsonTokenType.String -> printfn "Value: %s" (reader.GetString())
| JsonTokenType.Number -> printfn "Value: %d" (reader.GetInt32())
| _ -> ()
| 方法 | 优点 | 缺点 | |------|------|------| | System.Text.Json | .NET 内置,高性能,低分配 | 功能相对基础 | | Newtonsoft.Json | 功能丰富,成熟稳定 | 性能稍差,外部依赖 | | FSharp.Data | F# 友好,类型提供器强大 | 学习曲线较陡 |
选择建议:
没有搜到相关的文章