为了账号安全,请及时绑定邮箱和手机立即绑定

解组 yaml 时保持精度

解组 yaml 时保持精度

Go
吃鸡游戏 2023-03-15 14:57:46
我得到了这段代码:package mainimport ( "fmt" "gopkg.in/yaml.v2")func main() { kkk := "common:\n vartest1: 1.2000\n vartest2: 1.22233" tmp := map[string]interface{}{} yaml.Unmarshal([]byte(kkk), tmp) fmt.Println(tmp)}我期望的是 float 的精度与字符串保持一致。但我得到了这个输出:map[common:map[vartest1:1.2 vartest2:1.22233]]我试过这个:package mainimport ( "fmt" "gopkg.in/yaml.v2")type Myfloat64 float64func (e *Myfloat64) UnmarshalYAML(unmarshal func(interface{}) error) error { var test Myfloat64 err := unmarshal(&test) if err != nil {  return err } fmt.Println(test) *e = test return nil}func main() { kkk := "common:\n vartest1: 1.2000\n vartest2: 1.22233" tmp := map[string]interface{}{} yaml.Unmarshal([]byte(kkk), tmp) fmt.Println(tmp)}但是还UnmarshalYAML没有被调用,因为 Myfloat64 类型不在map[string]interface{}{}. 我必须确保map[string]interface{}{}不变,因为我不能有一个固定的结构来定义那个未编组的结构。有什么办法可以保持精度?输入必须是“common:\n vartest1: 1.2000\n vartest2: 1.22233”。不允许将 1.2000 更新为字符串。
查看完整描述

1 回答

?
牛魔王的故事

TA贡献1830条经验 获得超3个赞

有什么办法可以保持精度?

不要将字符串解析为浮点数,而是保留原始值,即保留string.

这是一个例子:

  • 注意#1:需要扩展代码才能处理其他类型。

  • 注意#2:这是使用yaml.v3


type Any struct {

    Val any

}


func (a Any) String() string {

    return fmt.Sprint(a.Val)

}


func (a *Any) UnmarshalYAML(n *yaml.Node) error {

    switch n.Kind {

    case yaml.MappingNode:

        m := map[string]Any{}

        if err := n.Decode(&m); err != nil {

            return err

        }

        a.Val = m

    case yaml.ScalarNode:

        switch n.Tag {

        case "!!float":

            // Don't parse the raw string value,

            // use it as is if you want to retain

            // its formatting.

            a.Val = n.Value

        }

    }

    return nil

}

在操场上试试。


# output:

map[common:map[vartest1:1.2000 vartest2:1.22233]]


查看完整回答
反对 回复 2023-03-15
  • 1 回答
  • 0 关注
  • 84 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号