英文:
How to calculate a total for a column inside a golang template?
问题
我在html/template中有这段代码:
{{ $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>
Transactions是带有TotalPrice DB字段的货币交易,根据Iris框架的规范,我有4个函数。
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),所以在range内部的{{ $TotalPrice }}将打印.TotalPrice的值,并且最后一行的$TotalPrice的值也将为0.0。那么在go模板中,以下代码的等效写法是什么:
nums := []int{2, 3, 4}
sum := 0
for _, num := range nums {
sum += num
}
fmt.Println("sum:", sum)
英文:
I have this code inside a html/template:
{{ $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>
Transactions are Money Transaction with TotalPrice DB Fields and I have 4 functions according Iris framework spec.
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)
})
I've note the $TotalPrice keeps the initial value (0.0) for every iteration so {{ $TotalPrice }} inside the range will print the .TotalPrice value and the value of $TotalPrice at the last row will be 0.0 too then what is the equivalent, inside go template, of:
nums := []int{2, 3, 4}
sum := 0
for _, num := range nums {
sum += num
}
fmt.Println("sum:", sum)
答案1
得分: 3
在Go的模板中,一旦声明了一个变量并给它赋值,就不能更改其值。在你的代码中发生的情况如下:
- 外部总价格的值被声明为
$TotalPrice := 0.0
,始终为0.0
,并且变量的作用域延伸到模板的末尾。 - 当你在
range
内部定义一个名为$TotalPrice
的变量时,尽管变量名相同,但会分配一个全新的变量。这个变量的值由FloatInc($TotalPrice, .TotalPrice)
给出。注意,参数$TotalPrice
指的是外部的总价格,即0.0
,所以这个语句相当于$TotalPrice := 0.0 + .TotalPrice
。因此,当你在每次迭代中打印$TotalPrice
时,你得到的是当前的.TotalPrice
,而不是累积的总价格。 - 在(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 }}
英文:
In Go's template, once you declare a variable and assign value to it, you can't change its value. What happen in your code are:
- The value of outer total price which is declared as
$TotalPrice := 0.0
is always0.0
, and the variable scope is extended to the end of the template. - When you defined a variable named
$TotalPrice
insiderange
, although the variable name is the same, a completely new variable will be allocated. The value assigned to this variable is given byFloatInc($TotalPrice, .TotalPrice)
. Note that argument$TotalPrice
refers to outer total price which is0.0
, so the statement will be equal to$TotalPrice := 0.0 + .TotalPrice
. Thus, when you print the$TotalPrice
in each iteration, you got current.TotalPrice
instead of accumulated total price. - The scope of variable declared in (2) is between
range
andend
. Thus when you print$TotalPrice
at the last row, you got the value of outer total price declared in (1), i.e.0.0
.
In your case, you need to declare a function which takes Transactions
as its argument then calculate the total inside the function, e.g.
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
})
then use it in the template as:
{{ $TotalPrice := sum .Transactions }}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论