Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic Method Parameters in Golang

I need help with making this work for any type.

I have got a function I need to accept other types that have ID property.

I have tried using interfaces but that did not work for my ID property case. Here is the code:

package main


import (
  "fmt"
  "strconv"
  )

type Mammal struct{
  ID int
  Name string 
}

type Human struct {  
  ID int
  Name string 
  HairColor string
}

func Count(ms []Mammal) *[]string { // How can i get this function to accept any type not just []Mammal
   IDs := make([]string, len(ms))
   for i, m := range ms {
     IDs[i] = strconv.Itoa(int(m.ID))
   }
   return &IDs
}

func main(){
  mammals := []Mammal{
    Mammal{1, "Carnivorious"},
    Mammal{2, "Ominivorious"},
  }

  humans := []Human{
    Human{ID:1, Name: "Peter", HairColor: "Black"},
    Human{ID:2, Name: "Paul", HairColor: "Red"},
  } 
  numberOfMammalIDs := Count(mammals)
  numberOfHumanIDs := Count(humans)
  fmt.Println(numberOfMammalIDs)
  fmt.Println(numberOfHumanIDs)
}

I get this

error prog.go:39: cannot use humans (type []Human) as type []Mammal in argument to Count

See Go Playground for more details here http://play.golang.org/p/xzWgjkzcmH

like image 478
Ikenna Avatar asked Feb 08 '15 10:02

Ikenna


People also ask

Is generic type parameter?

Generics means parameterized types. The idea is to allow type (Integer, String, … etc., and user-defined types) to be a parameter to methods, classes, and interfaces. Using Generics, it is possible to create classes that work with different data types.

What is type T in Golang?

While v is just an ordinary parameter, of some unspecified type, T is different. T is a new kind of parameter in Go: a type parameter. We say that PrintAnything[T] is a parameterized function, that is, a generic function on some type T.

Does Go support generic programming?

Go already supported a form of generic programming via the use of empty interface types. For example, we can write a single function that works for different slice types by using an empty interface type with type assertions and type switches.


1 Answers

You can't do precisely what you ask for in Go. Closest way to do things in Go would be something like this as shown in code below:

type Ids interface{
  Id() int
}

func (this Mammal) Id() int{
  return this.ID
} 

func (this Human) Id() int{
  return this.ID
} 


func Count(ms []Ids) *[]string {
...
    IDs[i] = strconv.Itoa(int(m.Id()))
...
}

func main(){
  mammals := []Ids{
    Mammal{1, "Carnivorious"},
    Mammal{2, "Ominivorious"},
  }

  humans := []Ids{
    Human{ID:1, Name: "Peter", HairColor: "Black"},
    Human{ID:2, Name: "Paul", HairColor: "Red"},
  }
  ...
}  

here is the working example

like image 80
Uvelichitel Avatar answered Sep 21 '22 08:09

Uvelichitel