MST
星途 面试题库

面试题:Rust中基于字符串的自定义序列化与反序列化

设计一个Rust结构体,结构体包含多个不同类型的字段,要求实现基于字符串的自定义序列化和反序列化。序列化时将结构体的字段以特定格式拼接成字符串,反序列化时能从该字符串正确恢复结构体实例。同时,要考虑处理可能出现的错误情况,如字符串格式不正确等。请详细描述你的设计方案并给出完整的实现代码。
24.9万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

设计方案

  1. 定义结构体:首先定义包含不同类型字段的结构体。
  2. 序列化:实现将结构体转换为特定格式字符串的方法。例如,可以使用分隔符将不同字段的值连接起来。
  3. 反序列化:实现从特定格式字符串恢复结构体实例的方法。需要根据分隔符拆分字符串,并将拆分后的部分转换为对应字段的类型。
  4. 错误处理:在反序列化过程中,若字符串格式不正确(如字段数量不匹配、类型转换失败等),应返回合适的错误。

代码实现

use std::fmt::{Display, Error as FmtError, Formatter};
use std::str::FromStr;

#[derive(Debug)]
struct MyStruct {
    field1: i32,
    field2: String,
    field3: f64,
}

impl Display for MyStruct {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
        write!(f, "{},{},{}", self.field1, self.field2, self.field3)
    }
}

impl FromStr for MyStruct {
    type Err = Box<dyn std::error::Error>;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let parts: Vec<&str> = s.split(',').collect();
        if parts.len() != 3 {
            return Err("Invalid string format: wrong number of fields".into());
        }
        let field1: i32 = parts[0].parse()?;
        let field2 = parts[1].to_string();
        let field3: f64 = parts[2].parse()?;
        Ok(MyStruct { field1, field2, field3 })
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_serialize_deserialize() {
        let original = MyStruct {
            field1: 123,
            field2: "hello".to_string(),
            field3: 45.67,
        };
        let serialized = original.to_string();
        let deserialized: Result<MyStruct, _> = serialized.parse();
        assert!(deserialized.is_ok());
        let deserialized = deserialized.unwrap();
        assert_eq!(original.field1, deserialized.field1);
        assert_eq!(original.field2, deserialized.field2);
        assert_eq!(original.field3, deserialized.field3);
    }

    #[test]
    fn test_invalid_format() {
        let invalid_str = "123,hello";
        let result: Result<MyStruct, _> = invalid_str.parse();
        assert!(result.is_err());
    }
}

上述代码中:

  1. MyStruct 结构体定义了三个不同类型的字段 field1i32 类型)、field2String 类型)和 field3f64 类型)。
  2. 实现了 Display 特征来进行序列化,将结构体以 field1,field2,field3 的格式拼接成字符串。
  3. 实现了 FromStr 特征来进行反序列化,从字符串中解析出结构体实例,并处理可能出现的格式错误。
  4. tests 模块中编写了测试用例,验证序列化和反序列化的正确性以及错误处理的情况。