Golang Parametric多态性?

时间:2014-07-22 16:15:18

标签: go

我写了一个函数以获得标准偏差 浮点数组,但我有问题,我怎么能用它 如果我有一系列的整数?
我不想为每种数据类型都有一个函数...

func StdDev(a []float64) float64 {
    var Prom float64
    sum := 0.0
    Total := 0.0
    n := len(a)
    N := float64(n)

    for i := 0; i < n; i++ {
        sum += a[i]
    }
    Prom = sum / N
    for i := 0; i < n; i++ {
        Total += (a[i] - Prom) * (a[i] - Prom)
    }
    Total = Total / N
    Total = math.Sqrt(Total)
    return Total
}

2 个答案:

答案 0 :(得分:4)

Go没有泛型,因此您无法同时编写涵盖[]int[]float64的解决方案。您必须使用简单的for循环将[]int中的值复制到[]float64,并将int中的float复制到a := []int{1,2,3,4} b := make([]float64, len(a)) for i := range a { b[i] = float64(a[i]) } StdDev(b) 。然后你可以使用你的功能。示例(type conversion):

func Avg(a []float64) (sum float64) {
    for i := range a {
        sum += a[i]
    }
    return sum / float64(len(a))
}

func StdDev(a []float64) (total float64) {
    prom := Avg(a)

    for i := range a {
        total += (a[i] - prom) * (a[i] - prom)
    }

    total = total / float64(len(a))

    return math.Sqrt(total)
}

您还可以做的是根据反射值编写函数,然后使用play。这样会更慢,更难以编写更多代码,因此效益值得怀疑。

代码样式

虽然这不是主题,但我可以提供帮助,但如果您使用reflect.MakeFunc进行循环,则会注意到您的代码可能看起来更好。此外,函数体中的变量以较低的大写字母写入。还有其他一些句法技巧,如range clauses。利用Go的这些功能,您的代码可能看起来更好:

{{1}}

答案 1 :(得分:1)

您可以使用界面,就像sort package那样:

http://play.golang.org/p/4N_UpFScoU

package main

import "math"

type Adder interface {
    Add(a float64) float64
}

type floatAdder float64

func (f floatAdder) Add(a float64) float64 {
    return float64(f) + a
}

type intAdder int

func (i intAdder) Add(a float64) float64 {
    return float64(i) + a
}

func StdDev(a []Adder) float64 {
    var Prom float64
    sum := 0.0
    Total := 0.0
    n := len(a)
    N := float64(n)

    for i := 0; i < n; i++ {
        sum = a[i].Add(sum)
    }
    Prom = sum / N
    for i := 0; i < n; i++ {
        Total += a[i].Add(-Prom) * a[i].Add(-Prom)
    }
    Total = Total / N
    Total = math.Sqrt(Total)
    return Total
}

func main() {
    floats := []Adder{floatAdder(1.0), floatAdder(2.0), floatAdder(3.0)}
    println(StdDev(floats))

    ints := []Adder{intAdder(1), intAdder(2), intAdder(3)}
    println(StdDev(ints))
}