Формат float в golang html/template

Я хочу отформатировать значение float64 до 2 знаков после запятой в golang html/template, скажем, в файле index.html. В файле .go я могу форматировать так:

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

Но я не знаю, как отформатировать его в шаблоне. Я использую gin-gonic/gin framework для бэкенда. Любая помощь будет оценена. Спасибо.


person Bhavana    schedule 15.12.2016    source источник


Ответы (4)


У вас есть много вариантов:

  • Вы можете решить отформатировать номер, например. используя 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
person icza    schedule 15.12.2016
comment
Спасибо за помощь. Но как я могу форматировать в самом шаблоне? Есть ли способ отформатировать? Или мне нужно также передать пользовательский тип в шаблон с другими данными? Пожалуйста помоги. - person Bhavana; 15.12.2016
comment
@ user29 См. случай n4: передается чистое число типа float64 (3.1415), и оно отформатировано в шаблоне: {{printf "%.2f" .n4}}. - person icza; 15.12.2016
comment
5-й вариант: используйте подшаблон: {{define "FloatFmt"}}{{printf "%.2f" .}}{{end}} и используйте его с {{template "FloatFmt"}}. Вы должны обернуть вызов блоком {{with}}, если значение не равно .: {{with .n0}}{{template "FloatFmt"}}{{end}}). - person dolmen; 01.02.2017
comment
@dolmen Хороший совет. О действии {{template}}: {{template "name"}} выполняет шаблон с nil данными, но вы можете передать ему любые данные, например. {{template "name" .n0}}, поэтому не нужно обертывать {{with}}. Хотя я думаю, что выполнение другого шаблона имеет худшую производительность, чем просто вызов функции. - person icza; 01.02.2017

Используйте printf встроенную функцию шаблона с "%.2f" format:

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

tmpl.Execute(os.Stdout, 123.456789)

Играть на игровой площадке

person dolmen    schedule 01.02.2017

Вы можете зарегистрировать 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})
}

Игровая площадка

person Nadh    schedule 15.12.2016
comment
Уже есть встроенная функция printf. Смотрите мой собственный ответ. - person dolmen; 01.02.2017

Правка: я ошибся насчет округления/усечения.

Проблема с форматированием %.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/

person Alexander Trakhimenok    schedule 05.04.2017