Rust将结构导出到json如何处理小数点问题

简述

标准的 serde_json 序列化器不支持直接对浮点数进行格式化限制。如果将浮点数转换成字符串,又太low逼。这里重点推荐rust_decimal。

rust 复制代码
#[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。这个魔术师:

rust 复制代码
#[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)
}

它能在结果中输出我们期望的格式:

javascript 复制代码
		{
			"datetime": "2025-04-30T15:09:01",
			"code": "603019",
			"name": "中科曙光",
			"weight": 1.3,
			"wnbz": 1.22,
			"chgp": 1.72,
        }

如果你需要对Decimal类型进行某种转换或实现,这是个好的例子,它用在dolphindb数据库中:

javascript 复制代码
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比较方便,它还是高精度金融计算库,不会在四舍五入时丢失精度 。更多信息自己查吧。

相关推荐
红烧code12 小时前
【Rust GUI开发入门】编写一个本地音乐播放器(9. 制作设置面板)
开发语言·后端·rust
爱吃香蕉的阿豪1 天前
.NET Core 中 System.Text.Json 与 Newtonsoft.Json 深度对比:用法、性能与场景选型
数据库·json·.netcore
红烧code1 天前
【Rust GUI开发入门】编写一个本地音乐播放器(11. 支持动态明暗主题切换)
rust·gui·theme·slint
千叶寻-1 天前
package.json详解
前端·vue.js·react.js·webpack·前端框架·node.js·json
红烧code1 天前
【Rust GUI开发入门】编写一个本地音乐播放器(7. 制作歌词显示面板)
rust·gui·slint
JordanHaidee2 天前
【Rust GUI开发入门】编写一个本地音乐播放器(13. 实现按键绑定)
rust
JordanHaidee2 天前
【Rust GUI开发入门】编写一个本地音乐播放器(14. 应用打包-制作安装程序)
rust
JordanHaidee2 天前
【Rust GUI开发入门】编写一个本地音乐播放器(12. 国际化应用-多语言支持)
rust
红烧code2 天前
【Rust GUI开发入门】编写一个本地音乐播放器(4. 绘制按钮组件)
rust·gui·svg·slint
睿麒2 天前
鸿蒙app开发中 拿到json文件数据进行动画的播放
json