<?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>Forem: Matt Dale</title>
    <description>The latest articles on Forem by Matt Dale (@matthewdale).</description>
    <link>https://forem.com/matthewdale</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%2Fuser%2Fprofile_image%2F643687%2F69efd71d-6101-4cf6-9a33-498f3a9ff63b.jpg</url>
      <title>Forem: Matt Dale</title>
      <link>https://forem.com/matthewdale</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/matthewdale"/>
    <language>en</language>
    <item>
      <title>The Go Playground: Using Modules</title>
      <dc:creator>Matt Dale</dc:creator>
      <pubDate>Mon, 06 Nov 2023 07:22:10 +0000</pubDate>
      <link>https://forem.com/matthewdale/the-go-playground-using-modules-3om5</link>
      <guid>https://forem.com/matthewdale/the-go-playground-using-modules-3om5</guid>
      <description>&lt;p&gt;This is part of an upcoming series about useful and surprising features of the &lt;a href="https://go.dev/play/"&gt;Go Playground&lt;/a&gt;. Follow me to read more about the Go Playground!&lt;/p&gt;




&lt;p&gt;The &lt;a href="https://go.dev/play/"&gt;Go Playground&lt;/a&gt; is extremely useful for sharing runnable Go code and testing out standard library functions, but what if you want to test out code that's in an external library? It turns out that the Go Playground can automatically fetch Go modules when you import packages that aren't in the standard library.&lt;/p&gt;

&lt;p&gt;Let's check out an example of generating a random UUIDv4 using the &lt;a href="https://pkg.go.dev/github.com/google/UUID"&gt;github.com/google/uuid&lt;/a&gt; package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/google/uuid"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewRandom&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://go.dev/play/p/w1R-2ig_AcY" class="ltag_cta ltag_cta--branded"&gt;Run&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;When we run that code, the Go playground fetches the &lt;a href="https://pkg.go.dev/github.com/google/UUID"&gt;github.com/google/uuid&lt;/a&gt; module, then compiles and runs our code. By default, the Go Playground fetches the latest available module version for the specified package. But what if we want to use a different version of the module?&lt;/p&gt;

&lt;h2&gt;
  
  
  Major Versions
&lt;/h2&gt;

&lt;p&gt;To fetch a different major version, add a &lt;a href="https://go.dev/ref/mod#major-version-suffixes"&gt;major version suffix&lt;/a&gt; to the import path and the Go Playground will fetch that major version instead! For example, to fetch package &lt;code&gt;mypackage&lt;/code&gt; from version &lt;code&gt;v2.x.x&lt;/code&gt; of the &lt;code&gt;github.com/name/example&lt;/code&gt; module, import package&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;github.com/name/example/v2/mypackage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's check out an example of writing a simple HTTP handler using &lt;a href="https://pkg.go.dev/github.com/go-chi/chi/v5"&gt;v5&lt;/a&gt; of the &lt;a href="https://github.com/go-chi/chi"&gt;github.com/go-chi/chi&lt;/a&gt; module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"io"&lt;/span&gt;
    &lt;span class="s"&gt;"net"&lt;/span&gt;
    &lt;span class="s"&gt;"net/http"&lt;/span&gt;
    &lt;span class="s"&gt;"os"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/go-chi/chi/v5"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/go-chi/chi/v5/middleware"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;chi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewRouter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hi"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;":8080"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sending request..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://localhost:8080/"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Reading response..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stdout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://go.dev/play/p/lRZYSapMqOU" class="ltag_cta ltag_cta--branded"&gt;Run&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;That example highlights another feature of the Go Playground: &lt;strong&gt;you can run and test local network services, like HTTP servers&lt;/strong&gt;! Your code can't access the Internet, but you can run  as many local services as the Go Playground sandbox can handle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Any Version
&lt;/h2&gt;

&lt;p&gt;So far we've let the Go Playground fetch the latest version and a specific major version, but we can also specify the exact version of a module if we want. To do that, we'll use another hidden feature of the Go Playground: &lt;strong&gt;you can add multiple source code files&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;In this example, we'll add a &lt;code&gt;go.mod&lt;/code&gt; file that specifically requests v1.11.7 of the &lt;a href="https://pkg.go.dev/go.mongodb.org/mongo-driver"&gt;go.mongodb.org/mongo-driver&lt;/a&gt; module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;

    &lt;span class="s"&gt;"go.mongodb.org/mongo-driver/version"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Driver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mod&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;
&lt;span class="n"&gt;module&lt;/span&gt; &lt;span class="n"&gt;mymodule&lt;/span&gt;

&lt;span class="n"&gt;require&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mongodb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;mongo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="m"&gt;.11.6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://go.dev/play/p/P_nnDYB0zIy" class="ltag_cta ltag_cta--branded"&gt;Run&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;That's all for now! In the next Go Playground post, we'll look at displaying images and GIFs in the Go Playground. Subscribe for more!&lt;/p&gt;

</description>
      <category>go</category>
      <category>playground</category>
      <category>modules</category>
    </item>
    <item>
      <title>Sometimes "math/rand" Uses Weighted Dice</title>
      <dc:creator>Matt Dale</dc:creator>
      <pubDate>Mon, 19 Jun 2023 03:39:28 +0000</pubDate>
      <link>https://forem.com/matthewdale/sometimes-mathrand-uses-weighted-dice-3hmm</link>
      <guid>https://forem.com/matthewdale/sometimes-mathrand-uses-weighted-dice-3hmm</guid>
      <description>&lt;p&gt;Go's &lt;a href="https://pkg.go.dev/math/rand"&gt;math/rand&lt;/a&gt; package provides pseudo-random number generators, or PRNGs, that are used in a ton of Go software. I've personally used the &lt;code&gt;math/rand&lt;/code&gt; package in the vast majority of Go projects I've worked on. It's great for generating IDs, shuffling lists, introducing jitter in timing, and lots of other things.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;code&gt;math/rand&lt;/code&gt; should not be used for security-sensitive purposes. For that, use &lt;a href="https://pkg.go.dev/crypto/rand"&gt;crypto/rand&lt;/a&gt; instead.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As with any PRNG, the number sequence appears random but is actually deterministic and depends on the &lt;a href="https://en.wikipedia.org/wiki/Random_seed"&gt;seed&lt;/a&gt; value. As a result, it's possible to get &lt;code&gt;math/rand&lt;/code&gt; to generate the exact same number sequence by giving it the same seed value.&lt;/p&gt;

&lt;p&gt;Let's look at an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Seed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int63&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int63&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="c"&gt;// Output: 5577006791947779410 8674665223082153551&lt;/span&gt;

&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Seed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int63&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int63&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="c"&gt;// Output: 5577006791947779410 8674665223082153551&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://go.dev/play/p/r6OLyKo6hv7" class="ltag_cta ltag_cta--branded"&gt;Go Playground&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;We used the same seed and got the same random numbers each time, just like we expected! Now let's try using different seed values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Seed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int63&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int63&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="c"&gt;// Output: 5577006791947779410 8674665223082153551&lt;/span&gt;

&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Seed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int63&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int63&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="c"&gt;// Output: 1543039099823358511 2444694468985893231&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://go.dev/play/p/4_2Ki3FC-td" class="ltag_cta ltag_cta--branded"&gt;Go Playground&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Great, we got different numbers! Let's try two more seed values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Seed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;243697394791045426&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int63&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int63&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="c"&gt;// Output: 5463449640670714849 6224151428804650039&lt;/span&gt;

&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Seed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;6474076765971414729&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int63&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int63&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="c"&gt;// Output: 5463449640670714849 6224151428804650039&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://go.dev/play/p/UT7U9dXtI8i" class="ltag_cta ltag_cta--branded"&gt;Go Playground&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Oops, that's not right. We gave it totally different seed values, but the sequences are the same. What happened?&lt;/p&gt;

&lt;p&gt;It turns out that &lt;code&gt;math/rand&lt;/code&gt; will sometimes generate the same number sequence for different seed values. The &lt;a href="https://pkg.go.dev/math/rand#Seed"&gt;rand.Seed&lt;/a&gt; function docs describe the unexpected behavior:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Seed values that have the same remainder when divided by 2&lt;sup&gt;31&lt;/sup&gt;-1 generate the same pseudo-random sequence.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's not great, that means &lt;code&gt;math/rand&lt;/code&gt; might generate the same number sequence even if our seed values don't repeat.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_Y2JF2VS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z8h1gbeokfsemjsjfxvm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_Y2JF2VS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z8h1gbeokfsemjsjfxvm.jpg" alt="Yelling formal man watching news on laptop" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why'd you do that &lt;code&gt;math/rand&lt;/code&gt;?! You're supposed to be (pseudo) random!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Automatic Seeds in Go 1.20
&lt;/h2&gt;

&lt;p&gt;If you've looked at the &lt;a href="https://pkg.go.dev/math/rand#Seed"&gt;rand.Seed&lt;/a&gt; documentation recently, you may have noticed that the function is deprecated. In fact, starting with Go 1.20, the package-global &lt;code&gt;math/rand&lt;/code&gt; PRNG is automatically initialized with a random seed value. Great, so we can ignore this seed nonsense and just live our lives, right?&lt;/p&gt;

&lt;p&gt;Mostly yes. However, it's still possible to run into problems with the new &lt;code&gt;math/rand&lt;/code&gt; automatic seed values. I found that if you start about 100,000 processes that generate numbers with &lt;code&gt;math/rand&lt;/code&gt; using the automatic seed values, two of those processes will probably generate the same sequence.&lt;/p&gt;

&lt;p&gt;
  Why 100,000? (click for details)
  &lt;br&gt;
This is an example of the &lt;a href="https://en.wikipedia.org/wiki/Birthday_problem"&gt;birthday paradox&lt;/a&gt;, which is the counterintuitive fact that you're likely to get a repeating value in a series of random numbers much sooner than you might expect. In this case, &lt;code&gt;rand.Seed&lt;/code&gt; basically truncates the &lt;code&gt;int64&lt;/code&gt; input into 31 bits of entropy. Based on that, we can calculate that we have about a 90% chance of getting a repeating value after generating 100,000 random 31-bit numbers.&lt;br&gt;


&lt;/p&gt;

&lt;p&gt;Granted, most use cases don't require starting 100,000 processes. However, it could cause problems if, for example, you deploy an agent to every container in a very large server fleet and you need those agents to generate different number sequences.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some Possible Fixes
&lt;/h2&gt;

&lt;p&gt;If that is a problem for us, is there anything we can do about it? Yes!&lt;/p&gt;

&lt;h3&gt;
  
  
  Use a different PRNG library.
&lt;/h3&gt;

&lt;p&gt;One solution is to use a different PRNG that doesn't suffer from the same unexpected behavior as &lt;code&gt;math/rand&lt;/code&gt;. &lt;a href="https://github.com/golang/go/issues/36133"&gt;Go issue #36133&lt;/a&gt; suggests a possible alternative is the &lt;a href="https://pkg.go.dev/golang.org/x/exp/rand"&gt;golang.org/x/exp/rand&lt;/a&gt; module, which implements a different type of PRNG. Importantly, the &lt;code&gt;x/exp/rand&lt;/code&gt; module does not truncate seed values, so is less likely to cause collisions between seeds. However, it is not automatically seeded like &lt;code&gt;math/rand&lt;/code&gt;, so you must provide a seed value yourself!&lt;/p&gt;

&lt;h3&gt;
  
  
  Use &lt;code&gt;crypto/rand&lt;/code&gt; instead.
&lt;/h3&gt;

&lt;p&gt;Another option is to use the &lt;a href="https://pkg.go.dev/crypto/rand"&gt;crypto/rand&lt;/a&gt; package instead, which uses the operating system's or runtime's cryptographically-secure randomness source. Cryptographically-secure RNGs are typically slower than PRNGs, but if you don't need to generating a ton of values, then using &lt;code&gt;crypto/rand&lt;/code&gt; can be a simple option.&lt;/p&gt;

&lt;h3&gt;
  
  
  Partition the PRNG values.
&lt;/h3&gt;

&lt;p&gt;A more complex solution is to "partition" the &lt;code&gt;math/rand&lt;/code&gt; output with a value that is different for each process. For example, consider the following code that generates hexadecimal strings to use as request IDs. It reads a random value from &lt;code&gt;crypto/rand&lt;/code&gt; at startup and appends that to all values read from &lt;code&gt;math/rand&lt;/code&gt;, reducing the probability of collisions between processes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;partition&lt;/span&gt; &lt;span class="kt"&gt;uint32&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;binary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cryptorand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Reader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;binary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LittleEndian&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;partition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;newRequestID&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%016x%08x"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Uint64&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;partition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://go.dev/play/p/hMm1SgsXWT-" class="ltag_cta ltag_cta--branded"&gt;Go Playground&lt;/a&gt;
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Adding partitions to pseudo-random values can change the distribution of values, so it's extremely important to understand how it affects your use case. For example, a new distribution of values might introduce "hotspots" in a database index that wasn't a problem without the partition.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Additional Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/golang/go/issues/54880"&gt;Go issue #54880&lt;/a&gt; - math/rand: seed global generator randomly&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/golang/go/issues/21835"&gt;Go issue #21835&lt;/a&gt; - proposal: use PCG Source in math/rand for Go 2&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;sup&gt;&lt;br&gt;
Cover photo is &lt;a href="https://www.pexels.com/photo/closeup-photo-of-two-red-dices-showing-4-and-5-965875/"&gt;Closeup Photo of Two Red Dices Showing 4 and 5&lt;/a&gt; by &lt;a href="https://www.pexels.com/@grizzlybear/"&gt;Jonathan Petersson&lt;/a&gt;&lt;br&gt;
Body photo is &lt;a href="https://www.pexels.com/photo/yelling-formal-man-watching-news-on-laptop-3760778/"&gt;Yelling formal man watching news on laptop&lt;br&gt;
&lt;/a&gt; by &lt;a href="https://www.pexels.com/@olly/"&gt;Andrea Piacquadio&lt;br&gt;
&lt;/a&gt;&lt;br&gt;
&lt;/sup&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>random</category>
      <category>prng</category>
    </item>
    <item>
      <title>Early Perspectives on Go Generics</title>
      <dc:creator>Matt Dale</dc:creator>
      <pubDate>Tue, 01 Mar 2022 07:26:31 +0000</pubDate>
      <link>https://forem.com/matthewdale/early-perspectives-on-go-generics-387m</link>
      <guid>https://forem.com/matthewdale/early-perspectives-on-go-generics-387m</guid>
      <description>&lt;p&gt;&lt;a href="https://tip.golang.org/doc/go1.18"&gt;Go 1.18&lt;/a&gt; is scheduled for release sometime soon (originally Feb 2022) and will be the first version of Go to support &lt;a href="https://en.wikipedia.org/wiki/Generic_programming"&gt;generic programming&lt;/a&gt;, commonly called "generics". The lack of generics in Go has been a contentious topic for a long time, as Ian Lance Taylor pointed out in his GopherCon presentation in 2019:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Go was released November 10, 2009. Less than 24 hours later, we saw the first comment about generics.&lt;br&gt;
— Ian Lance Taylor, &lt;a href="https://www.youtube.com/watch?v=WzgLqE-3IhY&amp;amp;t=39s"&gt;GopherCon 2019: Generics in Go&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are already lots of good &lt;a href="https://go.dev/blog/why-generics"&gt;articles&lt;/a&gt;, &lt;a href="https://go.dev/doc/tutorial/generics"&gt;tutorials&lt;/a&gt;, and &lt;a href="https://www.youtube.com/watch?v=Pa_e9EeCdy8"&gt;talks&lt;/a&gt; about generics in Go, so this article will just focus on the experience of writing and using generic code in Go.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclaimer:&lt;/em&gt; Go 1.18 is not released yet! These early perspectives on Go generics are using the latest &lt;a href="https://pkg.go.dev/golang.org/dl/gotip"&gt;&lt;code&gt;gotip&lt;/code&gt;&lt;/a&gt; version as of Feb 21, 2022. Some of the behaviors described in this article may change in the final release.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's the Big Deal with Generics?
&lt;/h2&gt;

&lt;p&gt;Before we get into what using generics in Go is like, let's take a step back and ask, "Why do developers use generics and what improvements do generics offer?" Let's turn to a quote by Alexander Stepanov, original designer of the &lt;a href="https://en.wikipedia.org/wiki/Standard_Template_Library"&gt;C++ Standard Template Library&lt;/a&gt;, for help:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Generic programming is about abstracting and classifying algorithms and data structures ... Its goal is the incremental construction of systematic catalogs of useful, efficient and abstract algorithms and data structures.&lt;br&gt;
— Alexander Stepanov, &lt;a href="http://stepanovpapers.com/history%20of%20STL.pdf"&gt;Short History of STL&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So generic programming is primarily about being able to focus on writing code once and using it many times with many types. How does it work in Go?&lt;/p&gt;

&lt;h3&gt;
  
  
  Go Generics: The Really Really Short Version
&lt;/h3&gt;

&lt;p&gt;Go generics adds a "type constraint" syntax that allows functions and types to specify multiple types that they can receive and return. Let's make that more concrete with a simple &lt;code&gt;Min&lt;/code&gt; function that accepts two numeric values and returns the minimum value of the two. Our &lt;code&gt;Min&lt;/code&gt; function can accept two parameters, both either an &lt;code&gt;int64&lt;/code&gt; or &lt;code&gt;float64&lt;/code&gt;, and returns a value the same type as the inputs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Min&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To call our generic &lt;code&gt;Min&lt;/code&gt; function, we call it with values that satisfy the type constraint, &lt;code&gt;int64&lt;/code&gt; in this case. The Go compiler infers appropriate types, resulting in code that looks the same as non-generic Go code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;12&lt;/span&gt;
&lt;span class="n"&gt;Min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// returns 5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a more in-depth look at generics in Go, check out the &lt;a href="https://go.dev/doc/tutorial/generics"&gt;(beta) Go generics tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Early Perspectives
&lt;/h2&gt;

&lt;p&gt;Here's what you came for, some selected early perspectives on using Go generics!&lt;/p&gt;

&lt;h3&gt;
  
  
  Generic Type Inference
&lt;/h3&gt;

&lt;p&gt;Type inference is a concept already familiar to most Go developers. When you assign a value to a variable using the &lt;code&gt;:=&lt;/code&gt; assignment operator, you're asking the Go compiler to infer the correct variable type. Go generics use a similar concept to try to determine the correct types to use when calling a generic function.&lt;/p&gt;

&lt;p&gt;The good news is type inference works great with function parameters! Calling functions that use generic input parameter types is very intuitive in most cases, and is often syntactically identical to calling non-generic functions.&lt;/p&gt;

&lt;p&gt;However, calling functions with a generic return type often requires you to specify the type in the call. For example, let's consider the following generic function that returns a positive infinity floating point value as a &lt;code&gt;float32&lt;/code&gt; or &lt;code&gt;float64&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Inf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="kt"&gt;float32&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Inf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's try to call the &lt;code&gt;Inf&lt;/code&gt; function to assign a &lt;code&gt;+Inf&lt;/code&gt; value to a &lt;code&gt;float64&lt;/code&gt; variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;
&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Inf&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Oops, we got a compile error!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./main.go:20:15: cannot infer T (./main.go:10:10)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead, we have to specify the function type explicitly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;
&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Inf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;]()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As a result, calling generic functions where the Go compiler can't use the input parameters to infer the return type can be somewhat awkward. There's an open discussion about whether or not Go should support generic function type inference when assigning to a variable &lt;a href="https://github.com/golang/go/issues/50285"&gt;here&lt;/a&gt;, but for now you have to declare the return type explicitly.&lt;/p&gt;

&lt;h3&gt;
  
  
  APIs and Type Switches
&lt;/h3&gt;

&lt;p&gt;Generics also gives us new options when we want to add functionality to APIs while maintaining backward compatibility. Consider a function &lt;code&gt;Do&lt;/code&gt; that takes an &lt;code&gt;int&lt;/code&gt; value and performs some action.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Do&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Perform some action with int x.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's say we want &lt;code&gt;Do&lt;/code&gt; to support either an &lt;code&gt;int&lt;/code&gt; or a &lt;code&gt;bool&lt;/code&gt;, and perform a different action for with each type. Before generics, we might have just added new functions &lt;code&gt;DoInt&lt;/code&gt; and &lt;code&gt;DoBool&lt;/code&gt;, and kept the &lt;code&gt;Do&lt;/code&gt; function to maintain API backward compatibility.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;DoInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Perform some action with int x.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;DoBool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Perform some action with bool x.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Do&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;DoInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With generics, we can add a type constraint to our &lt;code&gt;Do&lt;/code&gt; function to accept either an &lt;code&gt;int&lt;/code&gt; or a &lt;code&gt;bool&lt;/code&gt; and use a type switch to do the appropriate action for each type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Do&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="c"&gt;// Perform some action with int x.&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="c"&gt;// Perform some action with bool x.&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; &lt;code&gt;any&lt;/code&gt; is a new shorthand for &lt;code&gt;interface{}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We've reduced our API surface area by only using a single &lt;code&gt;Do&lt;/code&gt; function, and maintained API backward compatibility in most cases (calls to &lt;code&gt;Do&lt;/code&gt; using reflection may still be impacted), but the resulting implementation code is less clear than two separate functions. Additionally, there's no compile-time check to ensure that the type constraint and switch cases match, so they may get out-of-sync and lead to bugs.&lt;/p&gt;

&lt;p&gt;Whether or not it's a good idea to update APIs to accept more types using type constraints is still unclear. There is an open &lt;a href="https://github.com/golang/go/issues/45380"&gt;discussion&lt;/a&gt; about amending the type switch to work more gracefully with type parameters, so follow that if you're interested in the outcome!&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;p&gt;With more types come more tests! If your functions only support a single type, then you only need to test with values of a single type. Once your functions support many types, you need to test with values of every supported type. That can balloon into lots of test cases quickly!&lt;/p&gt;

&lt;p&gt;To complicate things, some common testing practices won't work when using generics. For example, anonymous functions and closures cannot use type parameters (check out the discussion &lt;a href="https://groups.google.com/g/golang-nuts/c/ulntjLeGYn4"&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;As a result, you may end up with quite large tests with lots of subtests and lots of test cases, like the ones &lt;a href="https://github.com/matthewdale/gmath/blob/main/gmath_test.go"&gt;here&lt;/a&gt;. We'll need to develop new testing best practices to handle the new challenges that come with testing generic code in Go.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Go generics will be available soon and may significantly change how we write Go. There is a lot to learn about the best ways to use Go generics and we will undoubtedly make plenty of mistakes along the way. Considering that, Rob Pike's &lt;a href="https://github.com/golang/go/issues/48918"&gt;suggestion&lt;/a&gt; to keep generics out of most of the standard library for the Go 1.18 release seems very wise.&lt;/p&gt;

&lt;p&gt;Finally, here's a plug for the &lt;a href="https://github.com/matthewdale/gmath"&gt;&lt;code&gt;gmath&lt;/code&gt;&lt;/a&gt; library, my attempt to write generic versions of commonly used functions from the Go &lt;a href="https://pkg.go.dev/math"&gt;&lt;code&gt;math&lt;/code&gt;&lt;/a&gt; package. Check it out if you need &lt;code&gt;math&lt;/code&gt; functions for numeric types other than &lt;code&gt;float64&lt;/code&gt;!&lt;/p&gt;

</description>
      <category>go</category>
      <category>generics</category>
    </item>
    <item>
      <title>Sending 😀 in Go</title>
      <dc:creator>Matt Dale</dc:creator>
      <pubDate>Wed, 14 Jul 2021 03:16:16 +0000</pubDate>
      <link>https://forem.com/matthewdale/sending-in-go-46bf</link>
      <guid>https://forem.com/matthewdale/sending-in-go-46bf</guid>
      <description>&lt;p&gt;So you're a Go developer and you're building your latest and greatest web app. You decide to add some extra flare to your JSON API by adding a 😀 to the end of your success message. You define a success message and marshal it as JSON.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;jsonMsg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}{&lt;/span&gt;
    &lt;span class="s"&gt;"ok"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;      &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Success 😀"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonMsg&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c"&gt;// -&amp;gt; {"message":"Success 😀","ok":true}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We got the JSON message we expected, including our 😀, so that worked. But how does the smiley face in our code editor end up in a JSON message without breaking something or requiring some kind of Base64-encoded image in the message? It turns out there are actually numerous standards and systems that must work together to make handling Unicode text, including &lt;a href="https://en.wikipedia.org/wiki/Emoji"&gt;Emoji&lt;/a&gt;, seamless.&lt;/p&gt;

&lt;p&gt;The first reason it works is because 😀 is not just any image, but an image that's part of a font (called a &lt;a href="https://en.wikipedia.org/wiki/Glyph"&gt;glyph&lt;/a&gt;) that your code editor and most other software use to display text. The image data is already present on your computer and was likely included in your operating system or downloaded with your code editor.&lt;/p&gt;

&lt;p&gt;The second reason it works is because your code editor, the Go compiler, the Go runtime, the JSON standard, and the Go JSON library all use Unicode text encoding, specifically &lt;a href="https://unicodebook.readthedocs.io/unicode_encodings.html#utf-8"&gt;UTF-8&lt;/a&gt; encoding. Unicode text is encoded as a series of "code points": numbers that tell your software which glyphs to display. UTF-8 is a Unicode encoding that stores text as a series of 8-bit values and represents code points as one to four 8-bit values. For a helpful summary of text encoding terminology, check out &lt;a href="https://stackoverflow.com/a/27331885/855419"&gt;this Stack Overflow post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Why is any of this important? For me, this exploration started when I was attempting to &lt;a href="https://github.com/mongodb/mongo-go-driver/pull/649"&gt;improve handling of Unicode surrogate pair values&lt;/a&gt; in the MongoDB Go driver's &lt;a href="https://docs.mongodb.com/manual/reference/mongodb-extended-json/"&gt;Extended JSON&lt;/a&gt; unmarshaler. Don't worry if that sounds like word salad now, we'll explore those concepts more later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unicode in Go
&lt;/h2&gt;

&lt;p&gt;Building on what we just learned about Unicode text encoding, let's quickly review how Go text types work. A Go &lt;code&gt;string&lt;/code&gt; is a wrapper around a byte array that typically holds UTF-8-encoded text (although it can technically contain any arbitrary bytes). A Go &lt;code&gt;rune&lt;/code&gt; represents a single Unicode code point and is an alias of &lt;code&gt;int32&lt;/code&gt;. A &lt;code&gt;string&lt;/code&gt; can be directly converted to and from a &lt;code&gt;[]byte&lt;/code&gt; or &lt;code&gt;[]rune&lt;/code&gt;. For more information about text representation in Go, read Rob Pike's 2013 blog post &lt;a href="https://blog.golang.org/strings"&gt;Strings, bytes, runes, and characters in Go&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's see that encoding in action by printing the &lt;code&gt;[]byte&lt;/code&gt; representation of our JSON message. Note that &lt;code&gt;json.Marshal&lt;/code&gt; returns the encoded JSON as a &lt;code&gt;[]byte&lt;/code&gt;, so we just need to print the returned variable instead of converting it to a &lt;code&gt;string&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonMsg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;// -&amp;gt; [123 34 109 101 115 115 97 103 101 34 58 34 83 117 99 99 101 115 115 33 32 240 159 152 128 34 44 34 115 117 99 99 101 115 115 34 58 116 114 117 101 125]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, we just got a bunch of numbers. Where's the 😀? Let's use the &lt;a href="https://golang.org/pkg/bytes/#IndexRune"&gt;&lt;code&gt;IndexRune&lt;/code&gt;&lt;/a&gt; function in the &lt;code&gt;"bytes"&lt;/code&gt; package to find the index of the 😀 glyph in the byte slice.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IndexRune&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonMsg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'😀'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;// -&amp;gt; 21&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, now we know where it is! Let's make sure reading the byte at index &lt;code&gt;idx&lt;/code&gt; gives us the 😀 we expected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonMsg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;span class="c"&gt;// -&amp;gt; ð&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Something's not right, we got &lt;code&gt;ð&lt;/code&gt;, not a smiley face. Remember earlier when we talked about how some Unicode code points need more than one byte when encoded as UTF-8? Let's try reading a few different size byte slices and see what we get.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonMsg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;span class="c"&gt;// -&amp;gt; �&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hmm, that's not a smiley face. We got &lt;code&gt;�&lt;/code&gt;, the &lt;a href="https://en.wikipedia.org/wiki/Specials_(Unicode_block)"&gt;Unicode replacement character&lt;/a&gt;, which means Go couldn't figure out how to decode the bytes as a valid UTF-8 string. Let's try reading more bytes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonMsg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;span class="c"&gt;// -&amp;gt; �&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nope.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonMsg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;span class="c"&gt;// -&amp;gt; �&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not yet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonMsg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;span class="c"&gt;// -&amp;gt; 😀&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There, we got a smiley face by decoding 4 bytes! What happens if we try to decode 5 bytes?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonMsg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;span class="c"&gt;// -&amp;gt; 😀"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OK, now we're getting extra code points. That makes sense because the maximum size a UTF-8 code point can be is 4 bytes. Going back to the original question, let's look at the UTF-8 bytes that represent a 😀.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonMsg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="c"&gt;// -&amp;gt; [240 159 152 128]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can confirm that the value we found is indeed a 😀 by building the byte slice literal and decoding it as a UTF-8 string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;240&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;159&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;152&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;128&lt;/span&gt;&lt;span class="p"&gt;}))&lt;/span&gt;
&lt;span class="c"&gt;// -&amp;gt; 😀&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We just successfully built a valid UTF-8 string from individual byte values!&lt;/p&gt;

&lt;p&gt;In the Go runtime, strings are UTF-8 encoded byte arrays, but what about the actual ".go" file? Let's try reading the "main.go" file we're writing and see how the 😀 glyph is encoded.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ioutil&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"main.go"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IndexRune&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'😀'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;span class="c"&gt;// -&amp;gt; 😀&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="c"&gt;// -&amp;gt; [240 159 152 128]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's the same as the Go &lt;code&gt;string&lt;/code&gt; encoding! In fact, the Go compiler expects ".go" files to be UTF-8-encoded. The consistency of UTF-8 text encoding across different software definitely makes handling 😀 in Go easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unicode in JSON
&lt;/h2&gt;

&lt;p&gt;Great, we understand how to encode and decode our 😀 glyph in Go source code and Go strings! But weren't we talking about JSON messages? That's right, we marshalled a JSON message with a 😀 and were trying to figure out how it worked. The short answer is that the &lt;a href="https://datatracker.ietf.org/doc/html/rfc7159#section-8.1"&gt;JSON Character Encoding specification&lt;/a&gt; says that JSON can contain any UTF-8-encoded text, including 😀. If that's true, we should be able to unmarshal a JSON message declared as a Go &lt;code&gt;string&lt;/code&gt; literal and converted to a &lt;code&gt;[]byte&lt;/code&gt;. Let's try.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`{"message":"Success 😀","ok":true}`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;// -&amp;gt; map[message:Success 😀 ok:true]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because a Go &lt;code&gt;string&lt;/code&gt; is UTF-8-encoded text, converting one to a &lt;code&gt;[]byte&lt;/code&gt; and using the &lt;code&gt;"encoding/json"&lt;/code&gt; package to unmarshal it works as expected.&lt;/p&gt;

&lt;h3&gt;
  
  
  Weird Unicode in JSON
&lt;/h3&gt;

&lt;p&gt;We've mostly answered our original question, but let's consider a world where some legacy software doesn't handle JSON messages with multi-byte UTF-8 code points correctly. What if we really, really need to limit our JSON messages to only ASCII values, but we still want to send the 😀?&lt;/p&gt;

&lt;p&gt;JSON actually supports encoding Unicode code points as "escape sequences" in strings, like &lt;code&gt;"\u2603"&lt;/code&gt;, which is the Unicode escape sequence for the snowman emoji (&lt;code&gt;☃&lt;/code&gt;). How do we get the Unicode escape sequence for 😀?&lt;/p&gt;

&lt;p&gt;The Go &lt;code&gt;"encoding/json"&lt;/code&gt; library doesn't support marshaling JSON with only ASCII values (there's an interesting discussion about that &lt;a href="https://github.com/golang/go/issues/39137"&gt;here&lt;/a&gt;), so let's try using the &lt;a href="https://golang.org/pkg/strconv/#QuoteToASCII"&gt;&lt;code&gt;QuoteToASCII&lt;/code&gt;&lt;/a&gt; function from the &lt;code&gt;"strconv"&lt;/code&gt; package to get a Unicode escape sequence.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strconv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QuoteToASCII&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"😀"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c"&gt;// -&amp;gt; "\U0001f600"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unicode escape sequences in JSON must start with &lt;code&gt;"\u"&lt;/code&gt; (lowercase), so let's lowercase that &lt;code&gt;"\U"&lt;/code&gt; and try to unmarshal our message, replacing the literal 😀 with the Unicode escape sequence.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`{"message":"Success \u0001f600","ok":true}`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;// -&amp;gt; map[message:Success f600 ok:true]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;
  Spoiler
  &lt;br&gt;
Unicode escape sequences output by &lt;code&gt;QuoteToASCII&lt;/code&gt; are always valid in Go &lt;code&gt;string&lt;/code&gt; literals, but are not always valid in JSON strings. Go &lt;code&gt;string&lt;/code&gt; literals support UTF-32 escape sequences that start with an uppercase &lt;code&gt;"\U"&lt;/code&gt; (e.g. &lt;code&gt;"\U0001f600"&lt;/code&gt;), but JSON does not.&lt;br&gt;


&lt;/p&gt;

&lt;p&gt;Oops, that didn't work. What happened to our Unicode escape sequence and our 😀? It turns out that JSON Unicode escape sequences must &lt;a href="https://datatracker.ietf.org/doc/html/rfc7159#section-7"&gt;start with &lt;code&gt;"\u"&lt;/code&gt; followed by exactly 4 hexadecimal digits&lt;/a&gt;. The JSON unmarshaler reads the first 4 hex digits (&lt;code&gt;"0001"&lt;/code&gt;), decodes it as the Unicode "start of heading" code point (a non-printing control character), then reads the following values &lt;code&gt;"f600"&lt;/code&gt; as a literal string. In fact, we can't encode 😀 as a single JSON Unicode escape sequence because its code point value requires 17 bits, which is more than the 16 bits we can write as 4 hex digits. The Unicode spec helpfully includes a quirky feature called &lt;a href="https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Surrogates"&gt;surrogate pairs&lt;/a&gt; that lets us encode Unicode code points larger than 16 bits as a pair of UTF-16 values. We can use the &lt;a href="https://golang.org/pkg/unicode/utf16/#EncodeRune"&gt;&lt;code&gt;EncodeRune&lt;/code&gt;&lt;/a&gt; function from the &lt;code&gt;"unicode/utf16"&lt;/code&gt; package to get those two UTF-16 runes, then use &lt;code&gt;strconv.QuoteToASCII&lt;/code&gt; again to get the corresponding Unicode escape sequence.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;utf16&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EncodeRune&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'😀'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;pairStr&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;rune&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strconv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QuoteToASCII&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pairStr&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c"&gt;// -&amp;gt; "\ufffd\ufffd"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That seems like it worked, but if we take a closer look we see that both Unicode escape sequences are &lt;code&gt;"\ufffd"&lt;/code&gt;, which is the escape sequence for the Unicode replacement character &lt;code&gt;�&lt;/code&gt;. We've run into one of the quirks of Unicode surrogate pairs, which is that each "surrogate half" is not individually a valid Unicode code point. As a result, when we convert our &lt;code&gt;[]rune&lt;/code&gt; into a &lt;code&gt;string&lt;/code&gt;, Go interprets each surrogate half as two separate invalid Unicode code points and replaces each with the Unicode replacement character. If we try to run just the &lt;code&gt;[]rune&lt;/code&gt; to &lt;code&gt;string&lt;/code&gt; conversion code, we see the same result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;rune&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;}))&lt;/span&gt;
&lt;span class="c"&gt;// -&amp;gt; ��&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alright, no &lt;code&gt;string&lt;/code&gt; this time. Let's use the &lt;a href="https://golang.org/pkg/fmt/#hdr-Printing"&gt;Unicode format verb&lt;/a&gt; from the &lt;code&gt;"fmt"&lt;/code&gt; package to get the raw Unicode code point for each surrogate half.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%U %U&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;// -&amp;gt; U+D83D U+DE00&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, let's write those as JSON Unicode escape sequences and try it again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`{"message":"Success \uD83D\uDE00","ok":true}`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;// -&amp;gt; map[message:Success 😀 ok:true]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It worked! To be clear, Unicode surrogate pairs are confusing and not necessary in the vast majority of cases, but they can help us understand how different Unicode encodings work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;If you write Go code, you use Unicode and UTF-8 all the time. Go's strong UTF-8 support probably isn't random, as Rob Pike and Ken Thompson, two of the original authors of Go, wrote the &lt;a href="https://www.cl.cam.ac.uk/~mgk25/ucs/UTF-8-Plan9-paper.pdf"&gt;original implementation of UTF-8&lt;/a&gt; in the Plan 9 operating system in 1992. Today, most common software handles UTF-8-encoded text properly, but when something doesn't work, understanding the layers of text encoding can be incredibly helpful to pinpoint the problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Additional Reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.christianfscott.com/rust-chars-vs-go-runes/"&gt;https://www.christianfscott.com/rust-chars-vs-go-runes/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dmitripavlutin.com/what-every-javascript-developer-should-know-about-unicode/"&gt;https://dmitripavlutin.com/what-every-javascript-developer-should-know-about-unicode/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;sup&gt;Cover photo &lt;a href="https://unsplash.com/photos/fIEywSUhwFU?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditShareLink"&gt;background&lt;/a&gt; by &lt;a href="https://unsplash.com/@jannerboy62?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Nick Fewings&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/smiley?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>json</category>
      <category>unicode</category>
      <category>mongodb</category>
    </item>
  </channel>
</rss>
