Rust自定义BigNum序列化/反序列化测试报错求助
问题分析与解决
报错原因
这个错误的核心是序列化与反序列化的格式不匹配:
- 你期望将
BigNum序列化为字符串,但默认的Serde序列化逻辑会把内部的BigInt转为数字字面量输出。 - 当数字大到超出JSON浮点数的精确表示范围时,JSON解析器会把该数字字面量识别为浮点数类型,而你的反序列化逻辑却在等待字符串类型,因此触发类型不匹配错误。
解决方法
需要为BigNum手动实现Serialize和Deserialize trait,强制序列化时输出字符串,反序列化时从字符串解析。
步骤1:确保依赖配置
在Cargo.toml中添加必要依赖:
[dependencies] serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" num-bigint = { version = "0.4", features = ["serde"] }
步骤2:实现自定义序列化/反序列化
use num_bigint::BigInt; use serde::{Serialize, Deserializer, Serializer}; #[derive(Debug, PartialEq)] struct BigNum(BigInt); // 自定义序列化:将BigInt转为字符串输出 impl Serialize for BigNum { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, { serializer.serialize_str(&self.0.to_string()) } } // 自定义反序列化:从字符串解析为BigInt impl<'de> Deserialize<'de> for BigNum { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>, { let num_str = String::deserialize(deserializer)?; let big_int = num_str.parse().map_err(serde::de::Error::custom)?; Ok(BigNum(big_int)) } } // 测试验证 #[cfg(test)] mod tests { use super::*; use serde_json; #[test] fn test_bignum_serde() { let original = BigNum(BigInt::from_str_radix( "1333333333333333300000000000000000000000000000000", 10, ).unwrap()); // 序列化 let json_str = serde_json::to_string(&original).unwrap(); assert_eq!(json_str, "\"1333333333333333300000000000000000000000000000000\""); // 反序列化 let deserialized = serde_json::from_str::<BigNum>(&json_str).unwrap(); assert_eq!(deserialized, original); } }
逻辑说明
- 序列化时,将
BigInt转为字符串,确保JSON输出是带引号的字符串类型,避免被解析成浮点数。 - 反序列化时,先读取字符串,再通过
parse方法转换为BigInt,与序列化格式完全匹配。
内容的提问来源于stack exchange,提问作者ipV4
相关产品推荐
相关产品推荐

