You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言中decimal.Decimal序列化反序列化及转字符串方法问询

关于github.com/shopspring/decimal的序列化反序列化与字符串转换方案

一、序列化与反序列化的最佳实现

github.com/shopspring/decimal 已原生实现json.Marshaler和json.Unmarshaler接口,直接使用标准库encoding/json进行序列化/反序列化就能保证值完全不变,无需额外处理逻辑。

示例代码:

package main

import (
	"encoding/json"
	"fmt"
	"github.com/shopspring/decimal"
)

type Payment struct {
	Amount decimal.Decimal `json:"amount"`
}

func main() {
	// 初始化高精度decimal值
	pay := Payment{Amount: decimal.NewFromInt(100).Div(decimal.NewFromInt(3))} // 100/3 = 33.3333333333...

	// 序列化
	jsonData, err := json.Marshal(pay)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(jsonData)) // 输出 {"amount":"33.33333333333333333333333333"}

	// 反序列化
	var newPay Payment
	err = json.Unmarshal(jsonData, &newPay)
	if err != nil {
		panic(err)
	}
	// 验证值是否完全一致
	fmt.Println(newPay.Amount.Equal(pay.Amount)) // 输出 true
}

如果使用其他序列化协议(如gob),decimal也实现了gob.GobEncoder和gob.GobDecoder接口,直接使用对应库即可,精度不会丢失。

二、decimal.Decimal转字符串的方法

decimal提供了多个方法用于转换为字符串,满足不同场景需求:

  • String(): 返回最简洁的字符串表示,自动省略末尾无意义的零,整数不会带小数部分
  • StringFixed(scale int): 返回指定小数位数的字符串,使用四舍五入规则
  • StringFixedBank(scale int): 返回指定小数位数的字符串,使用银行家舍入法(四舍六入五成双)

示例代码:

package main

import (
	"fmt"
	"github.com/shopspring/decimal"
)

func main() {
	d1 := decimal.NewFromFloat(123.45)
	d2 := decimal.NewFromFloat(123.4)
	d3 := decimal.NewFromFloat(123.455)

	fmt.Println(d1.String()) // 输出 "123.45"
	fmt.Println(d2.String()) // 输出 "123.4"

	fmt.Println(d2.StringFixed(2)) // 输出 "123.40"
	fmt.Println(d3.StringFixed(2)) // 输出 "123.46"

	fmt.Println(d3.StringFixedBank(2)) // 输出 "123.46"
	d4 := decimal.NewFromFloat(123.45)
	fmt.Println(d4.StringFixedBank(2)) // 输出 "123.45"
}

内容的提问来源于stack exchange,提问作者Raul Cejas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 01:20:06