【问题标题】:Format float in golang html/template在 golang html/模板中格式化浮点数
【发布时间】:2016-12-15 08:23:53
【问题描述】:

我想将 float64 值格式化为 golang html/template 中的 2 位小数,例如在 index.html 文件中。在.go 文件中,我可以像这样格式化:

strconv.FormatFloat(value, 'f', 2, 32)

但我不知道如何在模板中格式化它。我正在使用gin-gonic/gin 框架作为后端。任何帮助将不胜感激。谢谢。

【问题讨论】:

    标签: go format go-html-template


    【解决方案1】:

    你有很多选择:

    • 您可以决定格式化数字,例如在将其传递给模板执行之前使用fmt.Sprintf() (n1)
    • 或者您可以创建自己的类型,在其中定义String() string 方法,并根据自己的喜好进行格式化。这由模板引擎 (n2) 检查和使用。
    • 您也可以直接从模板中显式调用printf,并使用自定义格式字符串(n3)。
    • 虽然你可以直接调用printf,但这需要传递string的格式。如果您不想每次都这样做,您可以注册一个自定义函数来执行此操作 (n4)

    看这个例子:

    type MyFloat float64
    
    func (mf MyFloat) String() string {
        return fmt.Sprintf("%.2f", float64(mf))
    }
    
    func main() {
        t := template.Must(template.New("").Funcs(template.FuncMap{
            "MyFormat": func(f float64) string { return fmt.Sprintf("%.2f", f) },
        }).Parse(templ))
        m := map[string]interface{}{
            "n0": 3.1415,
            "n1": fmt.Sprintf("%.2f", 3.1415),
            "n2": MyFloat(3.1415),
            "n3": 3.1415,
            "n4": 3.1415,
        }
        if err := t.Execute(os.Stdout, m); err != nil {
            fmt.Println(err)
        }
    }
    
    const templ = `
    Number:         n0 = {{.n0}}
    Formatted:      n1 = {{.n1}}
    Custom type:    n2 = {{.n2}}
    Calling printf: n3 = {{printf "%.2f" .n3}}
    MyFormat:       n4 = {{MyFormat .n4}}`
    

    输出(在Go Playground上试试):

    Number:         n0 = 3.1415
    Formatted:      n1 = 3.14
    Custom type:    n2 = 3.14
    Calling printf: n3 = 3.14
    MyFormat:       n4 = 3.14
    

    【讨论】:

    • 感谢您的帮助。但是如何在模板本身中格式化?有没有办法格式化?或者我也必须将自定义类型与其他数据一起传递给模板?请帮忙。
    • @user29 参见n4 案例:传递了float64 类型的“纯”数字(3.1415),它在模板中的格式为:{{printf "%.2f" .n4}}
    • 第五个选项:使用子模板:{{define "FloatFmt"}}{{printf "%.2f" .}}{{end}} 并与{{template "FloatFmt"}} 一起使用。如果值不是 .: {{with .n0}}{{template "FloatFmt"}}{{end}},则必须使用 {{with}} 块包装调用。
    • @dolmen 好提示。关于{{template}} 操作:{{template "name"}} 使用nil 数据执行模板,但您可以将任何数据传递给它,例如{{template "name" .n0}},所以不需要用{{with}} 包裹。虽然,我认为执行另一个模板比调用一个函数性能更差。
    【解决方案2】:

    使用printf template built-in function"%.2f" format

    tmpl := template.Must(template.New("test").Parse(`The formatted value is = {{printf "%.2f" .}}`))
    
    tmpl.Execute(os.Stdout, 123.456789)
    

    Go Playgroung

    【讨论】:

      【解决方案3】:

      您可以注册FuncMap

      package main
      
      import (
          "fmt"
          "os"
          "text/template"
      )
      
      type Tpl struct {
          Value float64
      }
      
      func main() {
          funcMap := template.FuncMap{
              "FormatNumber": func(value float64) string {
                  return fmt.Sprintf("%.2f", value)
              },
          }
      
          tmpl, _ := template.New("test").Funcs(funcMap).Parse(string("The formatted value is = {{ .Value | FormatNumber  }}"))
      
          tmpl.Execute(os.Stdout, Tpl{Value: 123.45678})
      }
      

      Playground

      【讨论】:

      • 已经有一个printf 内置函数。请参阅我自己的答案。
      【解决方案4】:

      编辑:我错了舍入/截断。

      %.2f 格式的问题在于它不会舍入而是截断。

      我开发了一个基于 int64 的十进制类,用于处理浮点数、字符串解析、JSON 等的钱。

      它将金额存储为 64 位整数美分。可以很容易地从浮点数创建或转换回浮点数。

      也便于存储在数据库中。

      https://github.com/strongo/decimal

      package example
      
      import "github.com/strongo/decimal"
      
      func Example() {
          var amount decimal.Decimal64p2; print(amount)  // 0
      
          amount = decimal.NewDecimal64p2(0, 43); print(amount)  // 0.43
          amount = decimal.NewDecimal64p2(1, 43); print(amount)  // 1.43
          amount = decimal.NewDecimal64p2FromFloat64(23.100001); print(amount)  // 23.10
          amount, _ = decimal.ParseDecimal64p2("2.34"); print(amount)  // 2.34
          amount, _ = decimal.ParseDecimal64p2("-3.42"); print(amount)  // -3.42
      }
      

      适用于我的债务追踪应用https://debtstracker.io/

      【讨论】:

        猜你喜欢
        • 2019-10-18
        • 1970-01-01
        • 2014-05-08
        • 2019-07-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-17
        • 2010-10-14
        相关资源
        最近更新 更多