Как рассчитать итог для столбца внутри шаблона golang?

У меня есть этот код внутри html/шаблона:

{{ $TotalPrice := 0.0 }}
{{ range $i, $tx := .Transactions }}
{{ $TotalPrice := FloatInc $TotalPrice (StrToFloat .TotalPrice) }}
  <tr>
    <td>{{ inc $i 1 }}</td> 
    <td>{{ .Description.String }}</td>
    <td>{{ .Type }}</td>
    <td>{{ .TotalPrice }}</td>
    <td>{{ .Note }}</td>  
  </tr>  
{{ end }}
<tr>
  <td></td> 
  <td></td>
  <td></td>
  <td>{{ $TotalPrice }}</td>
  <td></td>
  <td></td>
</tr> 

Транзакции - это денежные транзакции с полями базы данных TotalPrice, и у меня есть 4 функции в соответствии со спецификацией Iris framework.

tmpl.AddFunc("dec", func(num int, step int) int {
    return num - step
})

tmpl.AddFunc("inc", func(num int, step int) int {
    return num + step
})

tmpl.AddFunc("FloatDec", func(num float64, step float64) float64 {
    return num - step
})

tmpl.AddFunc("FloatInc", func(num float64, step float64) float64 {
    return num + step
})

tmpl.AddFunc("StrToFloat", func(s string) (float64, error) {
    return strconv.ParseFloat(s, 64)
}) 

Я заметил, что $TotalPrice сохраняет начальное значение (0,0) для каждой итерации, поэтому {{$TotalPrice}} внутри диапазона будет печатать значение .TotalPrice, а значение $TotalPrice в последней строке тоже будет 0,0, тогда что эквивалент внутри шаблона go:

nums := []int{2, 3, 4}
sum := 0
for _, num := range nums {
    sum += num
}
fmt.Println("sum:", sum)

person Sr. Libre    schedule 29.08.2017    source источник


Ответы (1)


В шаблоне Go, как только вы объявите переменную и присвоите ей значение, вы не сможете изменить ее значение. Что происходит в вашем коде:

  1. Значение внешней общей цены, объявленное как $TotalPrice := 0.0, всегда равно 0.0, а область действия переменной расширяется до конца шаблона.
  2. Когда вы определили переменную с именем $TotalPrice внутри range, несмотря на то, что имя переменной такое же, будет выделена совершенно новая переменная. Значение, присвоенное этой переменной, определяется как FloatInc($TotalPrice, .TotalPrice). Обратите внимание, что аргумент $TotalPrice относится к внешней общей цене, которая равна 0.0, поэтому оператор будет равен $TotalPrice := 0.0 + .TotalPrice. Таким образом, когда вы печатаете $TotalPrice в каждой итерации, вы получаете текущую .TotalPrice вместо накопленной общей цены.
  3. Область действия переменной, объявленной в (2), находится между range и end. Таким образом, когда вы печатаете $TotalPrice в последней строке, вы получаете значение внешней общей цены, объявленное в (1), то есть 0.0.

В вашем случае вам нужно объявить функцию, которая принимает Transactions в качестве аргумента, а затем вычислить общее количество внутри функции, например.

tmpl.AddFunc("sum", func(transactions []Transaction) float64 {
    sum := 0.0
    for _, t := range transactions {
        if v, err := strconv.ParseFloat(t.TotalPrice, 64); err == nil {
            sum += v
        }
    }
    return sum
})

затем используйте его в шаблоне как:

{{ $TotalPrice := sum .Transactions }}
person putu    schedule 29.08.2017