要在Go中计算算术平均数(平均值),你应该自己编写一个函数,将一个数字片断作为输入,对该片断中的所有数值进行求和,并将求和除以元素的数量。
package main
import "fmt"
func mean(data []float64) float64 {
if len(data) == 0 {
return 0
}
var sum float64
for _, d := range data {
sum += d
}
return sum / float64(len(data))
}
func main() {
fmt.Println(mean([]float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}))
}
这个函数要求输入的片断是某种类型的,比如float64 。如果你想计算一个片断的平均值,例如int ,直到最近,你还必须写一个单独的函数,其不同之处在于它接受一个int 片断作为参数。另一个解决方案是在计算前将切片转换为float64 。然而,新版本的Go 1.18引入了泛型函数,使你可以简化这个问题。你所需要做的就是写一个通用的mean() ,这个函数可以接受任何数字类型的分片。
package main
import (
"fmt"
"golang.org/x/exp/constraints"
)
type Number interface {
constraints.Float | constraints.Integer
}
func mean[T Number](data []T) float64 {
if len(data) == 0 {
return 0
}
var sum float64
for _, d := range data {
sum += float64(d)
}
return sum / float64(len(data))
}
func main() {
fmt.Println(mean([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}))
fmt.Println(mean([]float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}))
}
在上面的例子中,我们从自定义约束条件声明开始。Number 接口是一个类型集,是由 constraints.Float和 constraints.Integer.
这是Go 1.18中与泛型一起发布的一个新特性--现在接口不仅可以有一组方法,还可以有一组类型。只要使用| 操作符来声明我们的泛型函数应该接受的类型集。在我们的例子中,我们接受 constraints.Float和 constraints.Integer类型,它们本身就是包含所有浮点和整点类型的类型集。
新mean() 函数的其余部分与非泛型版本相同。唯一不同的是,我们使用类型T ,而不是float64 作为输入数据。函数的结果仍然是float64 ,因为无论输入的是整数还是浮点数的片断,我们都可以得到一个浮点数作为均值的结果。