Parametric Golang polymorphism?

I wrote a function to get the standard deviation from an array of floats, but I have a problem, how can I use it if I have an array of ints?
I do not want to have a function for each 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 } 
+6
source share
2 answers

There are no generics in Go, so you cannot write a solution that covers []int and []float64 at the same time. You must copy the values ​​from []int to []float64 with a simple conversion for the loop and type 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 write a function based on reflection values ​​and then use reflect.MakeFunc . It will be slower, harder to do and write more code, so the advantage will be dubious.

Code Style

Although this is off topic, I cannot help but notice that your code may look better if you use a range of sentences for your loops. In addition, variables in the function body are written in the lower caps. There are other syntax tricks, such as named return values. Using these Go features, your code might look better:

 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) } 
+4
source

You can use interfaces, as well as a 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)) } 
+1
source

Source: https://habr.com/ru/post/972659/


All Articles