我得到了這段代碼:
package main
import (
"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 main
import (
"fmt"
"gopkg.in/yaml.v2"
)
type Myfloat64 float64
func (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 更新為字串。
uj5u.com熱心網友回復:
有什么辦法可以保持精度?
不要將字串決議為浮點數,而是保留原始值,即保留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]]
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/535734.html
標籤:去
