簡體   English   中英

如何正確序列化/反序列化 rust?

[英]How to properly serialize/deserialize rust?

我有多個結構對應於僅在運行時才知道的序列化/反序列化對象,例如:

#[derive(Serialize, Deserialize)]
struct Car{
    model: i32,
    year: i32
}

#[derive(Serialize, Deserialize)]
struct Person{
    name: String,
    age: i32
}

然后我有序列化和反序列化的功能:

fn deserialize(data: Vec<u8>){
    let msg = str::from_utf8(data);
    serde_json::from_str(msg);
}

fn serialize(&self, object: Car) -> String{
    let msg = serde_json::to_string(&object).unwrap();
    return msg;
}

如何使反序列化 function 反序列化為 Car 和 Person(可能還有許多其他不同類型)並返回 object? 我怎樣才能讓序列化 function 做同樣的事情:序列化 Car、Person 和其他對象(在函數的屬性中接受這些類型)?

您可以在Deserialize特征上使deserialize化泛型:

fn deserialize<'a, T: Deserialize<'a>>(data: &'a [u8]) -> T {
    let msg = str::from_utf8(data).unwrap();
    serde_json::from_str(msg).unwrap()
}

請注意,您需要一些生命周期,因為某些類型需要從反序列化字符串doc中借用。

您也可以使serialize通用:

fn serialize<T: Serialize>(object: &T) -> String {
    serde_json::to_string(object).unwrap()
}

操場

您想使用泛型函數來允許傳入不同的類型,並設置特征邊界以確保對象能夠被序列化/反序列化。 調用serialize時,會根據參數的類型推斷類型,但調用deserialize時,如果無法推斷,則需要使用 turbofish ( ::<> ) 指定類型。

use serde::{Serialize, Deserialize};
use std::str;

#[derive(Serialize, Deserialize)]
struct Car {
    model: i32,
    year: i32
}

#[derive(Serialize, Deserialize)]
struct Person {
    name: String,
    age: i32
}

// constrain output types to have the `Deserialize` trait
fn deserialize<'a, T>(data: &'a [u8]) -> T where T: Deserialize<'a> {
    let msg = str::from_utf8(data).unwrap();
    serde_json::from_str::<T>(msg).unwrap()
}

// shorthand for the above when `T` isn't needed in the function body
fn serialize(object: &impl Serialize) -> String {
    let msg = serde_json::to_string(object).unwrap();
    return msg;
}

fn main() {
    let car = Car { model: 7, year: 2077 };
    let person = Person { name: "Bob".to_string(), age: 42 };

    // types are infrerred from the parameters
    let car_json = serialize(&car);
    let person_json = serialize(&person);

    let _: Car = deserialize(car_json.as_bytes()); // output type can be inferred
    let _ = deserialize::<Car>(car_json.as_bytes()); // requres turbofish

    let _: Person = deserialize(person_json.as_bytes()); // works for `Person` too
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM