✨ How will Go Generics in Go 1.18 change your life? 💜

With the arrival of a long awaited update for some, or an update like the others for others. Generics in Go are about to be your new code companion in your Go projects.

A concrete example? Yes

For me one of the easiest ways to understand a …


This content originally appeared on DEV Community and was authored by DEV Community

With the arrival of a long awaited update for some, or an update like the others for others. Generics in Go are about to be your new code companion in your Go projects.

A concrete example? Yes

For me one of the easiest ways to understand a new feature is to have an example. Until 1.17 (without Generics) having a function that created a slice of an element was easy for a type but if you wanted to manage several types it was immediately less fun.

// 1.17 without generic
func JoinBool(elements ...bool) []bool {
  return elements
}

func JoinInt(elements ...int) []int {
  return elements
}

func JoinString(elements ...string) []int {
  return elements
}

func main() {
  slice := JoinInt(1, 2, 3)
  slice2 := JoinBool(true, true, false)
  slice3 := JoinString("a", "b", "c")
}

In 1.17, you had to create a function for each type and call it individually.

🎉 A new foe has appeared : Go Generic

// 1.18 with generics
func Join[E any](elements ...E) []E {
  return elements
}

func main() {
  slice := Join[int](1, 2, 3)
  slice2 := Join[bool](true, true, false)
  slice3 := Join[string]("a", "b", "c")
}

In 1.18 the generics allow you to program your types. Yes, I think it's sexy to say it like that!

What am I reading? From Go!
everything between [] is the definition of your types.

In the definition of the function func Join[E any](elements ...E) []E as well as in the call slice := Join[int](1, 2, 3).
The type is defined when the function is called and used in the function code.

Let's split the function Join with the call Join[int](1, 2, 3)

func Join[E any](elements ...E) []E {
  return elements
}

In the example above I create an E type which can be of type any (keyword to say that everything is accepted). If you want a hint of understanding, imagine that at runtime you replace all E by int in a dynamic way.

Your function will then run like this if I simplify

// E type become int
func Join(elements ...int) []int {
  return elements
}

Now I let you imagine with all the other guys
Do you see it? Do you feel the power of Generics?

any is the new interface{} ?

Yes, but... No. Until now, if you wanted a function to accept several types, you used the interface{} hack which allowed you to receive anything. However it was to be used with care! And a type check was mandatory.

Let's take our Join function coded with interface{} again

func Join(elements ...interface{}) ([]interface{}, error) {
  // Check the interface type
  switch t := elements.(type) {
    case []int, []string:
      return elements, nil
    default:
      return nil, errors.New("Unsupported type")
  }
}

func main() {
  slice, err := Join(1, 2, 3)
  if err != nil {
    panic(err)
  }
  // slice is now a type of `[]interface{}`
  // Not a good idea. A Disaster ! To convert to []int again we needs to apply 
  // a second for loop
  var intSlice = []int{}
  for _, v := range slice {
    // Cast and check if the type of the interface{} is castable to `int` type
    if intCasted, ok := v.(int); ok {
      intSlice := append(intSlice, intCasted)
    }
  }

  // intSlice is not usable after a lot of pain...
}

When you use interface{}, it is mandatory to test your cast. Otherwise it's a crash! The cast is done at runtime which is quite risky for your programs.

🎉 A new foe has appeared : Go Generic
Here they come again! Version 1.18 is much nicer to read now that we know that our types are defined and checked at buildtime. If you use an IDE like VSCode, it will even warn you before building.

any everywhere !

NO! Never assume to set any by default! You should only start with the desired types, and as a last resort use any.

You will say yes, but Atomys, how can I do if my function can receive several types? The answer is simple, you can list as many types as you want:

func JoinNumeric[E int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | float32 | float64](elemets ...E) []E

My function accepts here a generic type E which could ONLY be of type numeric.

Yikes, but I'll have to write this every time? No, don't worry!

It is possible to create your own type, using interfaces. And yes, they are not going to disappear.

Let's create our Numeric type!

type Numeric interface {
    int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | float32 | float64
}

And now let's update our Join function declaration

func JoinNumeric[E Numeric](elemets ...E) []E

WOW! So much cleaner. Yes I'll give you that.

This is a concrete example of what Go Generics can bring in 1.18. But that's not all two new features comparable and the constraints package. We will see that in a next article !

Thanks for taking the time to read my article, it was my first one !

🙏 Please don't hesitate to support me with a follow on Github/42Atomys and DEV.to/42Atomys. New Go projects are coming soon.

💜💜


This content originally appeared on DEV Community and was authored by DEV Community


Print Share Comment Cite Upload Translate Updates
APA

DEV Community | Sciencx (2022-03-09T17:20:37+00:00) ✨ How will Go Generics in Go 1.18 change your life? 💜. Retrieved from https://www.scien.cx/2022/03/09/%e2%9c%a8-how-will-go-generics-in-go-1-18-change-your-life-%f0%9f%92%9c/

MLA
" » ✨ How will Go Generics in Go 1.18 change your life? 💜." DEV Community | Sciencx - Wednesday March 9, 2022, https://www.scien.cx/2022/03/09/%e2%9c%a8-how-will-go-generics-in-go-1-18-change-your-life-%f0%9f%92%9c/
HARVARD
DEV Community | Sciencx Wednesday March 9, 2022 » ✨ How will Go Generics in Go 1.18 change your life? 💜., viewed ,<https://www.scien.cx/2022/03/09/%e2%9c%a8-how-will-go-generics-in-go-1-18-change-your-life-%f0%9f%92%9c/>
VANCOUVER
DEV Community | Sciencx - » ✨ How will Go Generics in Go 1.18 change your life? 💜. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/03/09/%e2%9c%a8-how-will-go-generics-in-go-1-18-change-your-life-%f0%9f%92%9c/
CHICAGO
" » ✨ How will Go Generics in Go 1.18 change your life? 💜." DEV Community | Sciencx - Accessed . https://www.scien.cx/2022/03/09/%e2%9c%a8-how-will-go-generics-in-go-1-18-change-your-life-%f0%9f%92%9c/
IEEE
" » ✨ How will Go Generics in Go 1.18 change your life? 💜." DEV Community | Sciencx [Online]. Available: https://www.scien.cx/2022/03/09/%e2%9c%a8-how-will-go-generics-in-go-1-18-change-your-life-%f0%9f%92%9c/. [Accessed: ]
rf:citation
» ✨ How will Go Generics in Go 1.18 change your life? 💜 | DEV Community | Sciencx | https://www.scien.cx/2022/03/09/%e2%9c%a8-how-will-go-generics-in-go-1-18-change-your-life-%f0%9f%92%9c/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.