Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
July 27, 2022 06:20 am GMT

Go Course: Generics

In this section, we will learn about Generics which is a much awaited feature that was released with Go version 1.18.

What are Generics?

Generics means parameterized types. Put simply, generics allow programmers to write code where the type can be specified later because the type isn't immediately relevant.

Let's take a look at an example to understand this better.

For our example, we have simple sum functions for different types such as int, float64, and string. Since method overriding is not allowed in Go we usually have to create new functions.

package mainimport "fmt"func sumInt(a, b int) int {    return a + b}func sumFloat(a, b float64) float64 {    return a + b}func sumString(a, b string) string {    return a + b}func main() {    fmt.Println(sumInt(1, 2))    fmt.Println(sumFloat(4.0, 2.0))    fmt.Println(sumString("a", "b"))}

As we can see, apart from the types, these functions are pretty similar.

Let's see how we can define a generic function.

func fnName[T constraint]() {    ...}

Here, T is our type parameter and constraint will be the interface that allows any type implementing the interface.

I know, I know, this is confusing. So, let's start building our generic sum function.

Here, we will use T as our type parameter with an empty interface{} as our constraint.

func sum[T interface{}](a, b T) T {    fmt.Println(a, b)}

Also, starting with Go 1.18 we can use any, which is pretty much equivalent to the empty interface.

func sum[T any](a, b T) T {    fmt.Println(a, b)}

With type parameters, comes the need to pass type arguments, which can make our code verbose.

sum[int](1, 2) // explicit type argumentsum[float64](4.0, 2.0)sum[string]("a", "b")

Luckily, Go 1.18 comes with type inference which helps us to write code that calls generic functions without explicit types.

sum(1, 2)sum(4.0, 2.0)sum("a", "b")

Let's run this and see if it works.

$ go run main.go1 24 2a b

Now, let's update the sum function to add our variables.

func sum[T any](a, b T) T {    return a + b}
fmt.Println(sum(1, 2))fmt.Println(sum(4.0, 2.0))fmt.Println(sum("a", "b"))

But now if we run this, we will get an error that operator + is not defined in the constraint.

$ go run main.go./main.go:6:9: invalid operation: operator + not defined on a (variable of type T constrained by any)

While constraint of type any generally works it does not support operators.

So let's define our own custom constraint using an interface. Our interface should define a type set containing int, float, and string.

typeset

Here's how our SumConstraint interface looks.

type SumConstraint interface {    int | float64 | string}func sum[T SumConstraint](a, b T) T {    return a + b}func main() {    fmt.Println(sum(1, 2))    fmt.Println(sum(4.0, 2.0))    fmt.Println(sum("a", "b"))}

And this should work as expected

$ go run main.go36ab

We can also use the constraints package which defines a set of useful constraints to be used with type parameters.

constraints-package

For that, we will need to install the constraints package.

$ go get golang.org/x/exp/constraintsgo: added golang.org/x/exp v0.0.0-20220414153411-bcd21879b8fd
import (    "fmt"    "golang.org/x/exp/constraints")func sum[T constraints.Ordered](a, b T) T {    return a + b}func main() {    fmt.Println(sum(1, 2))    fmt.Println(sum(4.0, 2.0))    fmt.Println(sum("a", "b"))}

Here we are using the Ordered constraint.

type Ordered interface {    Integer | Float | ~string}

~ is a new token added to Go and the expression ~string means the set of all types whose underlying type is string.

And it still works as expected.

$ go run main.go36ab

Generics is an amazing feature because it permits writing abstract functions that can drastically reduce code duplication in certain cases.

When to use generics

So, when to use generics? We can take the following use cases as an example:

  • Functions that operate on arrays, slices, maps, and channels.
  • General purpose data structures like stack or linked list.
  • To reduce code duplication.

Lastly, I will add that while generics are a great addition to the language, they should be used sparingly.

And, it is advised to start simple and only write generic code once we have written very similar code at least 2 or 3 times.

This article is part of my open source Go Course available on Github.

GitHub logo karanpratapsingh / go-course

Master the fundamentals and advanced features of the Go programming language

Go Course

Hey, welcome to the course, and thanks for learning Go. I hope this course provides a great learning experience.

This course is also available on my website as well as on Educative.io

banner

Table of contents

What is Go?

Go (also known as Golang) is a programming language developed at Google in 2007 and open-sourced in 2009.

It focuses on simplicity, reliability, and efficiency. It was designed to combine the efficacy, speed, and safety of a statically typed and compiled language with the ease


Original Link: https://dev.to/karanpratapsingh/go-course-generics-1ko3

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To