Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Golang Parametric polymorphism?

Tags:

go

I wrote a function in order to get the standard deviation from a array of floats, but I'm have a problem, how can I use it if I have a array of ints?
I dont want to have a function for every data type...

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
}
like image 699
user3613179 Avatar asked Jul 22 '14 16:07

user3613179


1 Answers

Go has no generics, so you are not able to write a solution that covers []int and []float64 at the same time. You have to copy the values from your []int to a []float64 using a simple for-loop and a type conversion from int to float. Then you can use your function. Example (play):

a := []int{1,2,3,4}
b := make([]float64, len(a))

for i := range a {
    b[i] = float64(a[i])
}

StdDev(b)

What you can also do is to write a function based on reflection values and then use reflect.MakeFunc. This would be slower, harder to make and more code to write so the benefit is questionable.

Code style

Although this is off-topic I can't help but noticing that your code may look nicer if you would use range clauses for your loops. Also, variables in a function body are written in lower caps. There are some other syntactic tricks such as named return values. Utilizing these features of Go, your code may look nicer:

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)
}
like image 68
nemo Avatar answered Sep 17 '22 18:09

nemo