A Concise Guide to the Latest Go Generics Draft Design
Tags: go, generics
Published: 2020-06-18 13:35:23

---
title: A Concise Guide to the Latest Go Generics Draft Design
published: true
description: Get up to date with the latest Go Generics Draft Design with this succinct guide
tags: golang, go, generics
cover_image: https://i0.wp.com/pmihaylov.com/wp-content/uploads/2020/06/go-generics.png?w=1352
canonical_url: https://pmihaylov.com/go-generics-draft-design/
---
<!-- wp:paragraph -->
<p>Recently, the Go team announced an <a href="https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md">updated draft design</a> for their Generics in Go proposal. It goes into a lot of details about why certain decisions were made, implementation details, etc.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In this article, my goal is to summarise the major upcoming changes, as the whole draft design can be a mouthful for many.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p> I will provide some code snippets to demonstrate the major features as well as give you the chance to experiment yourself with them, thanks to the <a href="https://go2goplay.golang.org/">new Go playground</a> with support for generics.</p>
<!-- /wp:paragraph -->

<!-- wp:more -->
<!--more-->
<!-- /wp:more -->

<!-- wp:heading -->
<h2>Type Constraints in Generic Functions</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Here's how a generic function looks like without any constraints on the type parameter:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
{%gist https://gist.github.com/preslavmihaylov/cbc409330f38fcf1955b6b67ad768512.js %}
<!-- /wp:html -->

<!-- wp:paragraph -->
<p><a href="https://go2goplay.golang.org/p/76fyt-j5jGo">Try it out!</a></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>To add constraints on the generic type, you can demand that it implements a given interface:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
{%gist https://gist.github.com/preslavmihaylov/c1387a51d21363462c3f86110436fd92.js %}
<!-- /wp:html -->

<!-- wp:paragraph -->
<p><a href="https://go2goplay.golang.org/p/1PdVsq036H8">Try it out!</a></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>To specify multiple type parameters, separate them by commas:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
{%gist https://gist.github.com/preslavmihaylov/66a74e49cdde131d844fce38107a0e1e.js %}
<!-- /wp:html -->

<!-- wp:paragraph -->
<p><a href="https://go2goplay.golang.org/p/dVJxy0tM1NC">Try it out!</a></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Constraints on multiple type parameters are written the same way you write function argument types:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
{%gist https://gist.github.com/preslavmihaylov/56dfcb7ca11d8d9907ff3690c70bef54.js %}
<!-- /wp:html -->

<!-- wp:paragraph -->
<p><a href="https://go2goplay.golang.org/p/FwkEp2spInY">Try it out!</a></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>And here's how to specify different types for both parameters:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
{%gist https://gist.github.com/preslavmihaylov/4905a9fdd45a8ddaaad3f068141f4100.js %}
<!-- /wp:html -->

<!-- wp:paragraph -->
<p><a href="https://go2goplay.golang.org/p/av_-VYA0-Rl">Try it out!</a></p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Type Lists &amp; comparable</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Instead of constraining types based on a set of methods, you can constraint them based on a set of supported types. For example, you could specify that you accept a generic type which can only be an int or a long.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This allows you to e.g. leverage operators like "less than", "greater than", which are only available for basic types in Go:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
{%gist https://gist.github.com/preslavmihaylov/7c877ff3db970ddd3cce9ec2f8387145.js %}
<!-- /wp:html -->

<!-- wp:paragraph -->
<p><a href="https://go2goplay.golang.org/p/W9c6vDaH7HJ">Try it out!</a></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>You also have an out-of-the-box constraint called <strong>comparable</strong>, which constraints types to those which support the == and != operators.</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
{%gist https://gist.github.com/preslavmihaylov/ed2f0ec290662434290f7f6765bd4852.js %}
<!-- /wp:html -->

<!-- wp:paragraph -->
<p><a href="https://go2goplay.golang.org/p/bcjlPyFxf8M">Try it out!</a></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Interfaces using these constraints - type lists and/or comparable, cannot be implemented by a struct. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>They can only be used for type constraint definitions.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Generic Types</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Structs can be defined using a generic type. Once specified, in the type declaration, there is no need to specify the type for all the functions of the type:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
{%gist https://gist.github.com/preslavmihaylov/fff80816397a94767c581767477e3b82.js %}
<!-- /wp:html -->

<!-- wp:paragraph -->
<p><a href="https://go2goplay.golang.org/p/34O9oLiHS_d">Try it out!</a></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>You can also do that in interfaces. This is especially useful when a type constraint depends on itself. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>E.g. you have a type constraint for <strong>T</strong>, which requires an <strong>Equal</strong> method, which accepts a <strong>T</strong> parameter:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
{%gist https://gist.github.com/preslavmihaylov/dc1372fc259ad8477d548bb174f46b01.js %}
<!-- /wp:html -->

<!-- wp:paragraph -->
<p><a href="https://go2goplay.golang.org/p/dTKRo-1Yeh3">Try it out!</a></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In case you need to specify a type parameter, who has a state-modifying function (e.g. a setter), then you can specify a pointer type constraint:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
{%gist https://gist.github.com/preslavmihaylov/d0b2c16b36525c5c337479676febb40f.js %}
<!-- /wp:html -->

<!-- wp:paragraph -->
<p><a href="https://go2goplay.golang.org/p/oy4O_oYxRn8">Try it out!</a></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Notice how this example above requires that you explicitly specify the type you'll use in the function - <strong>FromStrings(Settable)</strong>...</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This is because whenever the type is not present as a function argument, the compiler cannot infer the actual type once the code is compiled. Hence, you need to explicitly specify it.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Conclusion</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>This article was purposefully succinct and straightforward. Hopefully, it will help you quickly get up-to-date on the latest generics draft design, while you're drinking your morning coffee.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>However, there is a lot of rationale behind any single design choice around generics in Go. If you are interested to dive deeper into this subject, check out the <a href="https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md#type-parameters-draft-design">official draft design doc</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>So, do you like the latest Go Generics draft design?</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Let me know in the comments section below.</p>
<!-- /wp:paragraph -->