马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
简述
尺度的 serde_json 序列化器不支持直接对浮点数进行格式化限定。假如将浮点数转换成字符串,又太low逼。这里重点保举rust_decimal。- #[derive(Serialize)]
- pub struct StockTickRow {
- datetime: NaiveDateTime,
- code: String,
- name: String,
- #[serde(serialize_with = "serialize_float")]
- weight: f32,
- #[serde(serialize_with = "serialize_float")]
- wnbz: f32,
- #[serde(serialize_with = "serialize_float")]
- chgp: f32,
- }
- fn serialize_float<S>(value: &f32, serializer: S) -> Result<S::Ok, S::Error>
- where
- S: Serializer,
- {
- // 这种方式不行,只能转换成字符串了
- // let rounded_value = (value * 100.0).round() / 100.0;
- // serializer.serialize_f32(rounded_value)
- let formatted_value = format!("{:.2}", value); // 固定两位小数
- serializer.serialize_str(&formatted_value)
- }
复制代码 上面是一开始我接纳的方式,用了一天,心中不甘。就发现了rust_decimal。这个把戏师:- #[derive(Serialize, Deserialize)]
- pub struct StockTickRow {
- datetime: NaiveDateTime,
- code: String,
- name: String,
- #[serde(serialize_with = "serialize_decimal_two_digits")]
- weight: Decimal,
- #[serde(serialize_with = "serialize_decimal_two_digits")]
- wnbz: Decimal,
- }
- fn serialize_decimal_two_digits<S>(value: &Decimal, serializer: S) -> Result<S::Ok, S::Error>
- where
- S: serde::Serializer,
- {
- let rounded = value.round_dp(2);
- let float_value: f64 = rounded.try_into().unwrap_or(0.0); // 尝试转换,失败时返回默认值
- serializer.serialize_f64(float_value)
- }
复制代码 它能在效果中输出我们渴望的格式: - {
- "datetime": "2025-04-30T15:09:01",
- "code": "603019",
- "name": "中科曙光",
- "weight": 1.3,
- "wnbz": 1.22,
- "chgp": 1.72,
- }
复制代码 假如你必要对Decimal范例进行某种转换或实现,这是个好的例子,它用在dolphindb数据库中:- impl FromDolphinScalar for Decimal {
- fn from_scalar(scalar: &ScalarImpl) -> Option<Self> {
- match scalar {
- ScalarImpl::Float(c) => c.into_inner().map(|v| Decimal::from_f32(v).unwrap()),
- ScalarImpl::Double(c) => c.into_inner().map(|v| Decimal::from_f64(v).unwrap()),
- _ => None,
- }
- }
- }
复制代码 Rust-Decimal 除了输出json比力方便,它还是高精度金融盘算库,不会在四舍五入时丢失精度 。更多信息本身查吧。
|