layout

Rust序列化与反序列化

JSON序列化和反序列化

在Python中我们通常能非常方便的处理不同的文件,rust相较之下复杂一些,下面我将在几个常见场景下给出rust下的实现。首先是序列化,假设我们现在需要实现对简单词典信息的读写。单词信息如下:

{
  "hom": {
    "meaning": "man, human",
    "class": "root",
    "root": "hom",
    "example": ["homage", "homicide", "hominoid", "Homo sapiens"],
    "origin": "Latin"
  }
}

上面json对象中:hom表示一个结构,其中包含有如下字段:

  • meaning:含义
  • class:单词的类别,比如root表示单词类别是词根。
  • root:词根值
  • example:以此作为词根的例子。
  • origin:来源于什么字符集。
    在python中如果想要实现这段内容的序列化和反序列化非常简单,我们可以直接用字典:
import json


def dict_to_json(info, filename):
    with open(filename, "w") as f:
        json.dump(info, f)


def file_to_dict(filename):
    with open(filename, "r") as f:
        info = json.load(f)
    return info


if __name__ == "__main__":
    info = {
        "hom": {
            "meaning": "man, human",
            "class": "root",
            "root": "hom",
            "example": ["homage", "homicide", "hominoid", "Homo sapiens"],
            "origin": "Latin",
        }
    }
    filename = "temp.json"
    dict_to_json(info, filename)
    s_infp = file_to_dict(filename)

rust下实现相同的功能要复杂一些。

// serde = { version = "1.0.188", features = ["derive"] }
// serde_json
use serde::{Deserialize, Serialize};

use std::fs;
#[derive(Deserialize, Serialize, Debug)]
struct WordRoot {
    meaning: String,
    class: String,
    root: String,
    example: Vec<String>,
    origin: String,
}

fn info_to_json(info: &WordRoot, filename: &str) -> std::io::Result<()> {
    serde_json::to_writer_pretty(fs::File::create(filename)?, &info).expect("序列化失败");
    Ok(())
}
fn json_to_info(filename: &str) -> WordRoot {
    let serialized = fs::read_to_string(filename).unwrap();
    let deserialized: WordRoot = serde_json::from_str(&serialized).unwrap();
    deserialized
}
fn main() -> std::io::Result<()> {
    let info = WordRoot {
        meaning: "man, human".to_string(),
        class: "root".to_string(),
        root: "hom".to_string(),
        example: vec![
            "homeage".to_string(),
            "homicide".to_string(),
            "hominoid".to_string(),
            "Home sapiens".to_string(),
        ],
        origin: "Latin".to_string(),
    };
    let filename = "temp.json";
    let _ = info_to_json(&info, filename);
    println!("info = {:?}", info);
    let r = json_to_info(filename);
    println!("r = {:?}", r);
    Ok(())
}

实现上和python版本稍微有点区别,原因在于python的字典就可以很好的序列化和反序列化,所以python版本没有实现类似的结构体。

yaml文件的序列化和反序列化

import yaml


def dict_to_yaml(info, filename):
    with open(filename, "w") as f:
        yaml.dump(info, f)


def yaml_to_dict(filename):
    with open(filename, "r") as f:
        info = yaml.load(f, Loader=yaml.FullLoader)
    return info


if __name__ == "__main__":
    info = {
        "hom": {
            "meaning": "man, human",
            "class": "root",
            "root": "hom",
            "example": ["homage", "homicide", "hominoid", "Homo sapiens"],
            "origin": "Latin",
        }
    }
    filename = "info.yaml"
    info = dict_to_yaml(info, filename)
    y_info = yaml_to_dict(filename)
    print(f"y = {y_info}")

rust实现,添加库:serde_yaml = "0.9.25"


fn info_to_yaml(info: &WordRoot, filename: &str) -> std::io::Result<()> {
    serde_yaml::to_writer(fs::File::create(filename)?, &info).expect("序列化失败");
    Ok(())
}
fn yaml_to_info(filename: &str) -> WordRoot {
    let info: WordRoot = serde_yaml::from_str(&fs::read_to_string(filename).unwrap()).unwrap();
    info
}

toml文件读写

python实现:

import toml
import yaml


def dict_to_yaml(info, filename):
    with open(filename, "w") as f:
        yaml.dump(info, f)


def yaml_to_dict(filename):
    with open(filename, "r") as f:
        info = yaml.load(f, Loader=yaml.FullLoader)
    return info


def dict_to_toml(info, filename):
    with open(filename, "w") as f:
        toml.dump(info, f)


def toml_to_dict(filename):
    with open(filename, "r") as f:
        info = toml.load(f)
    return info


if __name__ == "__main__":
    info = {
        "hom": {
            "meaning": "man, human",
            "class": "root",
            "root": "hom",
            "example": ["homage", "homicide", "hominoid", "Homo sapiens"],
            "origin": "Latin",
        }
    }
    filename = "info.toml"
    dict_to_toml(info, filename)
    y_info = toml_to_dict(filename)
    print(f"y = {y_info}")

rust实现

需要包:``


   转载规则


《layout》 bleedingfight 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录