<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Golang</title>
    <description>The latest articles on DEV Community by Golang (@gophers).</description>
    <link>https://dev.to/gophers</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F4684%2Ffa50995b-f876-4511-900b-24900e084a96.png</url>
      <title>DEV Community: Golang</title>
      <link>https://dev.to/gophers</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gophers"/>
    <language>en</language>
    <item>
      <title>What are goroutines and how are they scheduled?</title>
      <dc:creator>Matt Boyle</dc:creator>
      <pubDate>Mon, 04 Apr 2022 07:25:59 +0000</pubDate>
      <link>https://dev.to/gophers/what-are-goroutines-and-how-are-they-scheduled-2nj3</link>
      <guid>https://dev.to/gophers/what-are-goroutines-and-how-are-they-scheduled-2nj3</guid>
      <description>&lt;p&gt;I use goroutines all the time, but I got asked about how they are scheduled recently and I did not know the answer to a sufficient depth. I find writing things down is a great way to ensure I understand them and thought I would turn my notes into a blog in an effort to help others! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you like this blog post and want to support me to write more whilst learning more about Go, you can check out my site &lt;a href="http://bytesizego.com" rel="noopener noreferrer"&gt;bytesizego.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What is a goroutine?
&lt;/h1&gt;

&lt;p&gt;Makes sense to start out answering this. &lt;/p&gt;

&lt;p&gt;Goroutines are the Go programming language's way of dealing with concurrency (allowing multiple things to happen at the same time). It's worth calling out the difference between concurrency and parallelism as it is an important thing to distinguish. I really like the the take Riteek Srivastav took in his blog post &lt;a href="https://riteeksrivastava.medium.com/a-complete-journey-with-goroutines-8472630c7f5c" rel="noopener noreferrer"&gt;here&lt;/a&gt;, so I have copied the paragraph below wholesale. His blog post is an excellent reference on goroutines, so if you want to go a bit deeper than I did here, please check it out:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Here’s an example: I’m writing this article and feel &lt;br&gt;
thirsty, I’ll stop typing and drink water. Then start &lt;br&gt;
typing again. Now, I’m dealing with two jobs (typing and &lt;br&gt;
drinking water) by some time slice, which is said to be &lt;br&gt;
concurrent jobs. Point to be noted here is that these two tasks (writing and drinking) are not being done at the same time. &lt;/p&gt;

&lt;p&gt;When things are being done at the same time it’s called &lt;br&gt;
parallelism (Think checking your mobile AND eating chips).&lt;br&gt;
So concurrency is dealing with multiple things at once &lt;br&gt;
(does not need to be done at the same time) with some time  schedule and parallelism(doing multiple things at the same time) is a subset of this. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;goroutines are cheap to create and very easy to use. Any function in go can be run concurrently by simply appending the &lt;code&gt;go&lt;/code&gt; keyword to the function call. &lt;/p&gt;

&lt;p&gt;A really naive use might look as follows:&lt;/p&gt;

&lt;p&gt;Without goroutines&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "context"
    "time"
)

// cancel is called as functions execute sequentially and take 4 seconds each.
func main() {
    ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
    defer cancel()
    someLongRunningTaskOne(ctx)
    someLongRunningTaskTwo(ctx)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With goroutines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "context"
    "time"
)

// The program executes the two functions concurrency.  
// We use a sleep to stop or programming terminating 
// prematurely. More on this below.
func main() {
    ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
    defer cancel()
    go someLongRunningTaskOne(ctx)
    go someLongRunningTaskTwo(ctx)

    time.Sleep(time.Second * 5)

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  So goroutines are threads?
&lt;/h1&gt;

&lt;p&gt;To people new to Go, the word goroutine and thread get used a little interchangeably. This makes sense if you come from a language such as Java where you can quite literally make new OS threads. Go is different, and a goroutine is not the same as a thread. Threads are much more expensive to create, use more memory and switching between threads takes longer. &lt;/p&gt;

&lt;p&gt;Goroutines are an abstraction over threads and a single Operating System thread can run many goroutines. &lt;/p&gt;

&lt;h1&gt;
  
  
  So How are goroutines scheduled?
&lt;/h1&gt;

&lt;p&gt;Firstly, we always have a &lt;code&gt;main&lt;/code&gt; goroutine. This is the programs main "thread" (see, it's hard to avoid this word when discussing them!). When this main goroutine terminates, our program is complete. You always need to keep this in mind as if we do not account for this in our program, you may see some unexpected behaviour. If you look at the example of using goroutines above again, the program will not wait for either of the goroutines to complete before terminating the program. This is why we have to use a &lt;code&gt;time.Sleep()&lt;/code&gt; but this means our program has a race condition.&lt;/p&gt;

&lt;p&gt;From this main goroutine, we can create as many goroutines as we like, and within those goroutines, we can create goroutines. The below is totally valid go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "log"
    "time"
)

func main() {
    go func() {
        go func() {
            go func() {
                go func() {
                    go func() {
                        go func() {
                            go func() {
                                log.Println("maybe I should have thought about this program a little more")
                            }()
                        }()
                    }()
                }()
            }()
        }()
    }()
    time.Sleep(time.Second)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Are goroutines called in the order I declared them?
&lt;/h1&gt;

&lt;p&gt;No.&lt;/p&gt;

&lt;p&gt;Most Operating Systems have something called a preemptive scheduler. This means that which thread is executed next is determined by the OS itself based on thread priority and other things like waiting to receive data over the network. Since goroutines are abstractions over threads, they all have the same priority and we therefore cannot control the order in which they run.&lt;/p&gt;

&lt;p&gt;There has been discussions as far back as 2016 (you can read one such discussion &lt;a href="https://groups.google.com/g/golang-dev/c/HJcGESXfJfs" rel="noopener noreferrer"&gt;here&lt;/a&gt;) about adding the ability to set priority on individual goroutines, but there is some pretty compelling points raised as to why its not a good idea. &lt;/p&gt;

&lt;h1&gt;
  
  
  How do I ensure my program is as performant as possible?
&lt;/h1&gt;

&lt;p&gt;There is an environment variable (&lt;code&gt;GOMAXPROCS&lt;/code&gt;) that you can set which determines how many threads your go program will use simultaneously. You can use this great library from &lt;a href="https://github.com/uber-go/automaxprocs" rel="noopener noreferrer"&gt;Uber&lt;/a&gt; to automatically set the &lt;code&gt;GOMAXPROCS&lt;/code&gt; variable to match a Linux container CPU quota. If you are running Go workloads in Kubernetes, you should use this. &lt;/p&gt;

&lt;p&gt;If you set &lt;code&gt;GOMAXPROCS&lt;/code&gt; to be 3, this means that the program will only execute code on 3 operating system threads at once, even if there are 1000s of goroutines.&lt;/p&gt;

&lt;p&gt;It begs the question though, does setting &lt;code&gt;GOMAXPROCS&lt;/code&gt; to the biggest value possible mean your program will be faster? &lt;/p&gt;

&lt;p&gt;The answer is no, and it actually might make it slower. There are a few reasons for this, but the main reason is to do with context switching.&lt;/p&gt;

&lt;p&gt;Swapping between threads is a relatively slow operation, and &lt;a href="https://eli.thegreenplace.net/2018/measuring-context-switching-and-memory-overheads-for-linux-threads/" rel="noopener noreferrer"&gt;can take up to 1000ns&lt;/a&gt; as oppose to switching between goroutines on the same thread which takes ~200ns. Therefore you may find that for your particular workload, your program is faster with a lower &lt;code&gt;GOMAXPROCS&lt;/code&gt; value. Always profile and benchmark your programs and make sure the Go runtime configuration is only changed if absolutely required.&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;I hope you found this useful and you came away with a better understanding of what goroutines are how they are scheduled. For more Go tidbits, or to say hey, you find me on Twitter &lt;a href="https://twitter.com/home" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Further Reading
&lt;/h1&gt;

&lt;p&gt;As well as the links referenced above, I found the following blogs/articles incredibly valuable whilst researching this blogpost, and I highly recommend reading them if you want to dive a little bit further into this topic.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.ardanlabs.com/blog/2018/08/scheduling-in-go-part1.html" rel="noopener noreferrer"&gt;https://www.ardanlabs.com/blog/2018/08/scheduling-in-go-part1.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.nindalf.com/posts/how-goroutines-work/" rel="noopener noreferrer"&gt;https://blog.nindalf.com/posts/how-goroutines-work/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://golangbyexample.com/goroutines-golang/" rel="noopener noreferrer"&gt;https://golangbyexample.com/goroutines-golang/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dave.cheney.net/tag/gomaxprocs" rel="noopener noreferrer"&gt;https://dave.cheney.net/tag/gomaxprocs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>programming</category>
      <category>cloud</category>
    </item>
    <item>
      <title>What are go workspaces and how do I use them?</title>
      <dc:creator>Matt Boyle</dc:creator>
      <pubDate>Mon, 21 Mar 2022 08:46:21 +0000</pubDate>
      <link>https://dev.to/gophers/what-are-go-workspaces-and-how-do-i-use-them-1643</link>
      <guid>https://dev.to/gophers/what-are-go-workspaces-and-how-do-i-use-them-1643</guid>
      <description>&lt;p&gt;I previously blogged about &lt;a href="https://dev.to/gophers/what-are-go-generics-when-should-i-use-them-39bg"&gt;generics&lt;/a&gt; being added as part of the Go 1.18 release. There was another quality of life improvement that was added with this release called "Go workspaces". &lt;/p&gt;

&lt;p&gt;This is what the release notes said about workspaces:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqeyve0g3xy0ihqtf2pqt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqeyve0g3xy0ihqtf2pqt.png" alt="workspace documentation from release notes, https://tip.golang.org/doc/go1.18" width="800" height="100"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this blog post, we are going to explore what Go workspaces are and how to use them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you like this blog post and want more great Go content, check out &lt;a href="http://bytesizego.com" rel="noopener noreferrer"&gt;bytesizego.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  go mod replace
&lt;/h2&gt;

&lt;p&gt;Have you ever wanted to make a change to one of the Go modules your code depends on? After some googling you might have found yourself doing something similar to the below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module test1.18

go 1.18

require golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect

replace golang.org/x/sync =&amp;gt; ./local/sync
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should be all we need. To test it I copied the code from &lt;code&gt;golang.org/x/sync&lt;/code&gt; to &lt;code&gt;./local/sync&lt;/code&gt;. My file tree looks like this:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftr55pp9g93fahw3xrrkk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftr55pp9g93fahw3xrrkk.png" alt="File tree" width="762" height="470"&gt;&lt;/a&gt;&lt;br&gt;
and then made a small edit to the &lt;code&gt;Go&lt;/code&gt; func of errgroup:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8hqmemmvofxbwusvlahm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8hqmemmvofxbwusvlahm.png" alt="Log line added to Go func or errgroup" width="800" height="595"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and wrote a simple main func:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fullj7l7kfz049tfbm2qz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fullj7l7kfz049tfbm2qz.png" alt="Simple main func calling eg.Go" width="688" height="894"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As expected, when I run my program I get the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2022/03/21 07:58:10 Let's go!
2022/03/21 07:58:10 did a thing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, everything works!&lt;/p&gt;

&lt;p&gt;Before go 1.18, this was pretty much the only way to make changes to multiple modules at once. You would then need to remember to remove your changes from &lt;code&gt;go.mod&lt;/code&gt; before you commit your code. &lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing Workspaces
&lt;/h2&gt;

&lt;p&gt;With workspaces, this whole process becomes much easier. We can make a &lt;code&gt;go.work&lt;/code&gt; file that effectively works the same as the &lt;code&gt;replace&lt;/code&gt; directive we used previously. Let's follow the same example again but this time use a workspace file.&lt;/p&gt;

&lt;p&gt;My go.mod file is reverted to be as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module test1.18

go 1.18

require golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I then make a new file called &lt;code&gt;go.work&lt;/code&gt; at the root of my project and added the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go 1.18

use ./local/sync
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's truly it! The go tool detects the workspace file automatically and uses it. When I run &lt;code&gt;go run ./workspace/main.go&lt;/code&gt; I get the same output as before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2022/03/21 08:03:43 Let's go!
2022/03/21 08:03:43 did a thing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the Go 1.18 Beta you were able to run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; go build -workfile=off ./workspace/main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to build the code without using the workfile, but this didn't work for me with the production release. I raised a bug against the go tool &lt;a href="https://github.com/golang/go/issues/51838" rel="noopener noreferrer"&gt;here&lt;/a&gt; and it looks like it was removed before release which is a shame.  &lt;/p&gt;

&lt;p&gt;The correct way to do is now to run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GOWORK=off go run ./workspace/main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and with this we get the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2022/03/21 08:27:03 did a thing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This shows it is now building with the original module in our go.mod file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best practises and Warnings
&lt;/h2&gt;

&lt;p&gt;Early posts from the community are suggesting that not committing your &lt;code&gt;go.work&lt;/code&gt; file is preferable. This makes sense, it is used for local development and after you have made and tested your changes to a module, you should push it, tag it and then reference it in your &lt;code&gt;go.mod&lt;/code&gt; file as usual. Therefore, sharing &lt;code&gt;go.work&lt;/code&gt; files doesn't make sense. &lt;/p&gt;

&lt;p&gt;Consider adding &lt;code&gt;go.work&lt;/code&gt; to your &lt;code&gt;.gitignore&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A Warning though, if you do happen to push your &lt;code&gt;go.work&lt;/code&gt; file it looks like if you run &lt;code&gt;go build&lt;/code&gt; it will use your &lt;code&gt;go.work&lt;/code&gt; file by default unless you explicitly turn it off. This could lead to production builds having development code in unintentionally. It therefore might be worth always running production builds with &lt;code&gt;GOWORK=off go build ./...&lt;/code&gt; to be on the safe side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap up
&lt;/h2&gt;

&lt;p&gt;I hope you find this useful. For more go tidbits, you can find me over on twitter &lt;a href="https://twitter.com/mattjamesboyle" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>programming</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>What are Go Generics &amp; When Should I use Them?</title>
      <dc:creator>Matt Boyle</dc:creator>
      <pubDate>Wed, 16 Mar 2022 07:28:48 +0000</pubDate>
      <link>https://dev.to/gophers/what-are-go-generics-when-should-i-use-them-39bg</link>
      <guid>https://dev.to/gophers/what-are-go-generics-when-should-i-use-them-39bg</guid>
      <description>&lt;p&gt;Yesterday Go 1.18 was released! &lt;/p&gt;

&lt;p&gt;1.18 has been eagerly awaited by the Go Community as it contained the official support of generics in Go as well as a whole host of other features which I hope to cover off in other blog posts in the future. You can read more about the release in the official release notes &lt;a href="https://tip.golang.org/doc/go1.18" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you like this blog post and want to support me to write more whilst learning more about Go, you can check out my site &lt;a href="http://bytesizego.com" rel="noopener noreferrer"&gt;bytesizego.com&lt;/a&gt;. I have both free and paid courses and writing.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For this blog post, we are going to focus on the following bullet from the notes:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;gt; The syntax for function and type declarations now accepts type parameters.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Type Parameters? What are They?
&lt;/h2&gt;

&lt;p&gt;Type parameters are Go's way to support generics. Generic's allow developers to write "general" code that works for many different data types without having to specify that at the point of code creation. I know that is confusing, so let's look at an example. &lt;/p&gt;

&lt;p&gt;Before Go 1.18, lets say we had the following slices we wanted to sum together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func main() {
    intsToAdd := []int{1, 2, 3, 4}
    floatsToAdd := []float64{1.1, 2.2, 3.3, 4.4}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We would need to write the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func sumInts(nums []int) int {
    var res int
    for _, num := range nums {
        res += num
    }
    return res
}

func sumFloats(nums []float64) float64 {
    var res float64
    for _, num := range nums {
        res += num
    }
    return res
}

func main() {
    intsToAdd := []int{1, 2, 3, 4}
    floatsToAdd := []float64{1.1, 2.2, 3.3, 4.4}

    fmt.Println("ints", sumInts(intsToAdd))
    fmt.Println("floats", sumFloats(floatsToAdd))
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which outputs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ints 10
floats 11
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works and there is nothing wrong with it at all. In fact, I imagine some teams will choose to continue to write code like the above due to its clarity.&lt;/p&gt;

&lt;p&gt;However, it does lead to a lot of &lt;em&gt;very similar&lt;/em&gt; functions as you can see. &lt;/p&gt;

&lt;p&gt;With the introduction of generics, we can write this much more succinctly as the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func main() {
    intsToAdd := []int{1, 2, 3, 4}
    floatsToAdd := []float64{1.1, 2.2, 3.3, 4.4}

    fmt.Println("ints", sumNumbers(intsToAdd))
    fmt.Println("floats", sumNumbers(floatsToAdd))
}

type Number interface {
    int | int64 | float32 | float64
}

func sumNumbers[n Number](nums []n) n {
    var res n
    for _, num := range nums {
        res += num
    }
    return res
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This looks pretty confusing to me since I'm not used to it, but I'm hoping over time I get more comfortable reading code like this. &lt;/p&gt;

&lt;p&gt;Let's step through it.&lt;/p&gt;

&lt;p&gt;Firstly we declare an interface which is going to be our type &lt;em&gt;constraint&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Number interface {
    int | int64 | float32 | float64
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are saying anything that is an int, an int64, a float32 or float64 is a &lt;code&gt;Number&lt;/code&gt;. Whenever we reference &lt;code&gt;Number&lt;/code&gt;, it must be one of these things. This is similar to how we have used Go interfaces in the past.&lt;/p&gt;

&lt;p&gt;In the square brackets below we add our type constraint &lt;code&gt;Number&lt;/code&gt; and call it &lt;code&gt;n&lt;/code&gt;. This means whenever we reference &lt;code&gt;n&lt;/code&gt; we are referring to the &lt;code&gt;Number&lt;/code&gt; type. The Compiler will do some clever work at compile time to figure out everything else for us.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func sumNumbers[n Number](nums []n)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have told our function that anytime we reference &lt;code&gt;n&lt;/code&gt; we are referencing either an int int64, float32 or float64, we can fill in the rest of the code.&lt;/p&gt;

&lt;p&gt;Please note that generics does not make the following valid.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// trying to mix ints and floats
NumsToAdd := []Number{1.1,-3, 2.2, 3.3, 4.4}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is because our &lt;code&gt;Number&lt;/code&gt; interface contains a &lt;code&gt;constraint&lt;/code&gt; types which means it cannot be used like this (confusing I know).&lt;/p&gt;

&lt;h2&gt;
  
  
  When should I use Generics?
&lt;/h2&gt;

&lt;p&gt;There is a video from Go team engineer Ian Lance Taylor &lt;a href="https://www.youtube.com/watch?v=nr8EpUO9jhw" rel="noopener noreferrer"&gt;here&lt;/a&gt; which does a great job of walking through use cases. I highly recommend watching it.&lt;/p&gt;

&lt;p&gt;In general, it is advised to start with simple functions and only try and write generic functions once you have wrote very similar code 2 or 3 times. In the example above, I would not have considered writing a generic function until I had wrote the &lt;code&gt;sumFloats&lt;/code&gt; function and realised how similar it was to the &lt;code&gt;sumInts&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Hope you found this useful! You can find me on twitter &lt;a href="https://twitter.com/mattjamesboyle" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>programming</category>
      <category>generics</category>
    </item>
  </channel>
</rss>
