Golang Generics

type Fooable interface {
Foo() int64
}
type fooImpl struct {}func (fooImpl) Foo() int64 {
return 0
}
type anotherFooImpl struct {}func (anotherFooImpl) Foo() int64 {
return 1
}
func Consume[F Fooable](fooable F) {
fmt.Printf("foo=\"%d\"\n", fooable.Foo())
}
// to test:
// Consume(fooImpl{})
// Consume(anotherFooImpl{})
type Consumer[F Fooable] interface {
Consume(foo F)
}
type consumerImpl[F Fooable] struct {}func (c *consumerImpl[F]) Consume(fooable F) {
fmt.Printf("foo=\"%d\"\n", fooable.Foo())
}
// to test:
// d := &consumerImpl[fooImpl]{}
// d.Consume(fooImpl{})
// d.Consume(anotherFooImpl{})
type genericConsumer struct {}
func (g *genericConsumer) Consume[F Fooable](fooable F) {
fmt.Printf("foo=\"%d\"", fooable.Foo())
}
// to test
// g := &genericConsumer{}
// g.Consume(fooImpl{})
// g.Consume(anotherFooImpl{})
package mainimport (
"fmt"
)
type Fooable interface {
Foo() int64
}
// non-object-orientedfunc Consume[F Fooable](fooable F) {
fmt.Printf("method=\"Consume\" foo=\"%d\"\n", fooable.Foo())
}
// set up for generic struct
type Consumer[F Fooable] interface {
Consume(foo F)
}
type fooImpl struct {}func (fooImpl) Foo() int64 {
fmt.Printf("struct=\"fooImpl\" method=\"Foo\"\n")
return 0
}
type anotherFooImpl struct {}func (anotherFooImpl) Foo() int64 {
fmt.Printf("struct=\"anotherFooImpl\" method=\"Foo\"\n")
return 1
}
type consumerImpl[F Fooable] struct {
}
func (c *consumerImpl[F]) Consume(fooable F) {
fmt.Printf("struct=\"consumerImpl\" method=\"Consume\" foo=\"%d\"\n", fooable.Foo())
}
// type genericConsumer struct {}
// func (g *genericConsumer) Consume[F Fooable](fooable F) {
// fmt.Printf("struct=\"genericConsumer\" method=\"Consume\" foo=\"%d\"", fooable.Foo())
// }
func main() {

// non-object-oriented.
fmt.Printf("section=\"non-object-oriented\" msg=\"begin\"\n")
Consume(fooImpl{})
Consume(anotherFooImpl{})
fmt.Printf("section=\"non-object-oriented\" msg=\"done\"\n\n")
fmt.Printf("section=\"typed struct\" msg=\"begin\"\n")
d := &consumerImpl[fooImpl]{}
d.Consume(fooImpl{})
// this would fail since `anotherFooImpl` doesn't neet the generic constraint for `consumerImpl`
// d.Consume(anotherFooImpl{})
fmt.Printf("section=\"typed struct\" msg=\"done\"\n\n")
// as of golang 1.18.3, this is not allowed:
// > syntax error: method must have no type parameters
// more details: https://github.com/golang/go/issues/49085
// g := &genericConsumer{}
// g.Consume(fooImpl{})
// g.Consume(anotherFooImpl{})
}

--

--

--

Minimalist. Game Developer. Software Engineer. DevOps enthusiast. Foodie. Gamer.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

GIT & GIT HUB 2 day workshop by Vimal Daga (Linux World Informatics)

Programmers Should Step Out of Their Comfort Zone

10 Practical Uses of AWK Command in Linux or Unix

Best 7 Application of Stack in Data Structure with Operation

Best 7 Application of Stack in Data Structure with Operation

DATA STRUCTURES & ALGORITHMS

Looking back today with three vaccines on the verge of being approved, it’s incredible to think…

Hand pose controlled car racing.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Xing Du

Xing Du

Minimalist. Game Developer. Software Engineer. DevOps enthusiast. Foodie. Gamer.

More from Medium

TicTacGo — An Intro to Golang

Get a file extension from a URL in Golang

Golang Field Alignment