<?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: Gwenaël NARDIN</title>
    <description>The latest articles on DEV Community by Gwenaël NARDIN (@yeswearecoding).</description>
    <link>https://dev.to/yeswearecoding</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%2F835408%2Fa56261c2-361c-48a8-8ec4-5a423f666cd9.png</url>
      <title>DEV Community: Gwenaël NARDIN</title>
      <link>https://dev.to/yeswearecoding</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yeswearecoding"/>
    <language>en</language>
    <item>
      <title>Nouvelle version de Go : 1.18</title>
      <dc:creator>Gwenaël NARDIN</dc:creator>
      <pubDate>Fri, 25 Mar 2022 21:17:30 +0000</pubDate>
      <link>https://dev.to/yeswearecoding/nouvelle-version-de-go-118-4dgn</link>
      <guid>https://dev.to/yeswearecoding/nouvelle-version-de-go-118-4dgn</guid>
      <description>&lt;h2&gt;
  
  
  Generics
&lt;/h2&gt;

&lt;p&gt;On peut définir la programmation générique comme un style de programmation qui permet de représenter des fonctions et des structures de données sous une forme générique, avec des types adaptés. Ca, c’est pour la théorie. Voyons un exemple.&lt;/p&gt;

&lt;p&gt;Pour illustrer le principe, imaginons que nous avons besoins de calculer la somme des éléments d’un &lt;code&gt;map&lt;/code&gt; de &lt;code&gt;int64&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="c"&gt;// SumInts adds together the values of m.&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;SumInts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&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="kt"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;v&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;s&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rien d’exceptionnel.&lt;/p&gt;

&lt;p&gt;Maintenant, si nous avons besoin de faire de même pour un &lt;code&gt;map&lt;/code&gt; de &lt;code&gt;float64&lt;/code&gt;, notre fonction pourrait être quelque chose de ce genre :&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="c"&gt;// SumFloats adds together the values of m.&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;SumFloats&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&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="kt"&gt;float64&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;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;v&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;s&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On constate la très grande similarité entre nos deux fonctions ; rien ne change à part le type.&lt;/p&gt;

&lt;h3&gt;
  
  
  Déclarer une fonction générique
&lt;/h3&gt;

&lt;p&gt;Pour pouvoir utiliser des valeurs de plusieurs types, il faut écrire une fonction qui déclare des &lt;code&gt;type parameters&lt;/code&gt; en plus des paramètres de fonction habituels.&lt;/p&gt;

&lt;p&gt;Chaque &lt;code&gt;type parameter&lt;/code&gt; a une contrainte qui permet de spécifier le type d'argument qui peut être accepté par la fonction. &lt;/p&gt;

&lt;p&gt;Notre fonction générique peut se définir ainsi :&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="c"&gt;// SumIntsOrFloats sums the values of map m. It supports both int64 and float64&lt;/span&gt;
&lt;span class="c"&gt;// as types for map values.&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;SumIntsOrFloats&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;K&lt;/span&gt; &lt;span class="n"&gt;comparable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;V&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;m&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;K&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="n"&gt;V&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;V&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;V&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;v&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;s&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On peut déclarer les contraintes comme une interface et modifier la fonction en conséquence :&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;type&lt;/span&gt; &lt;span class="n"&gt;Number&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&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="c"&gt;// SumNumbers sums the values of map m. It supports both integers&lt;/span&gt;
&lt;span class="c"&gt;// and floats as map values.&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;SumNumbers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;K&lt;/span&gt; &lt;span class="n"&gt;comparable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;V&lt;/span&gt; &lt;span class="n"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;K&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="n"&gt;V&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;V&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;V&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;v&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;s&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Cas d’usage
&lt;/h3&gt;

&lt;p&gt;La généricité peut être utile pour les fonctions qui font :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trouver le plus petit/grand élément d’un &lt;code&gt;slice&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Trouver la déviation moyenne/standard d’un &lt;code&gt;slice&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Calculer l’union/intersection de &lt;code&gt;maps&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Trouver le chemin le plus court d’un nœud d’un graphe&lt;/li&gt;
&lt;li&gt;Appliquer une fonction de transformation à un &lt;code&gt;slice&lt;/code&gt;/&lt;code&gt;map&lt;/code&gt;, qui retourne un &lt;code&gt;slice&lt;/code&gt; de résultat&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dans les cas plus spécifique à l’utilisation de la concurrence en &lt;strong&gt;Go&lt;/strong&gt;, on pourrait avoir les cas d’usages suivant :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lire un canal avec un &lt;em&gt;timeout&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Combiner deux canaux en un seul&lt;/li&gt;
&lt;li&gt;Appeler une liste de fonctions en parallèle, renvoyer un &lt;code&gt;slice&lt;/code&gt; de résultat&lt;/li&gt;
&lt;li&gt;Appeler une liste de fonctions, en utilisant un &lt;em&gt;Context&lt;/em&gt;, retourner le résultat de la première fonction qui termine, annuler et nettoyer les autres &lt;em&gt;goroutines&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Aller plus loin
&lt;/h3&gt;

&lt;p&gt;Les exemples et les explications sont tirés &lt;a href="%5Bhttps://go.dev/doc/tutorial/generics%5D(https://go.dev/doc/tutorial/generics)"&gt;de ce tutoriel&lt;/a&gt; (et également plus complet).&lt;/p&gt;

&lt;p&gt;Une &lt;a href="https://go.dev/blog/intro-generics"&gt;introduction publiée sur le blog officiel&lt;/a&gt; de Go.&lt;/p&gt;

&lt;p&gt;Les détails sont dans la &lt;a href="%5Bhttps://go.dev/doc/go1.18#generics%5D(https://go.dev/doc/go1.18#generics)"&gt;release note&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Des explications sur le pourquoi, les cas d’usages classiques : &lt;a href="%5Bhttps://go.dev/blog/why-generics%5D(https://go.dev/blog/why-generics)"&gt;Why Generics ?&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fuzzing
&lt;/h2&gt;

&lt;p&gt;Le &lt;em&gt;fuzzing&lt;/em&gt; est l’injection de données aléatoires dans un test afin de tenter de trouver une vulnérabilités ou de détecter des potentielles entrées qui pourraient faire &lt;em&gt;crasher&lt;/em&gt; un programme. Voyons un exemple de mise en œuvre.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exemple
&lt;/h3&gt;

&lt;p&gt;On prend une fonction qui inverse le sens d’une chaîne de caractères :&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;Reverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&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;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;:=&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="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&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="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&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="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&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="n"&gt;j&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="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&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;b&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;Cette fonction prend une &lt;code&gt;string&lt;/code&gt; en entrée, itère octet (&lt;code&gt;byte&lt;/code&gt;) par octet et renvoi la &lt;code&gt;string&lt;/code&gt; inversée.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Nota&lt;/em&gt;: ce code est basé sur la fonction &lt;code&gt;stringutil.Reverse&lt;/code&gt; de &lt;code&gt;golang.org/x/example&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ajoutons un test unitaire :&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;"testing"&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;TestReverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&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="n"&gt;testcases&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;want&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;}{&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Hello, world"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"dlrow ,olleH"&lt;/span&gt;&lt;span class="p"&gt;},&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="s"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"!12345"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"54321!"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tc&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;testcases&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;rev&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Reverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;in&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;rev&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;want&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Reverse: %q, want %q"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;want&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Il s’agit d’un simple test qui s’assure que la &lt;code&gt;string&lt;/code&gt; d'entrée est bien inversée.&lt;/p&gt;

&lt;p&gt;Remplaçons maintenant ce test classique par un test en &lt;em&gt;fuzzing&lt;/em&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;FuzzReverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;testcases&lt;/span&gt; &lt;span class="o"&gt;:=&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="s"&gt;"Hello, world"&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="s"&gt;"!12345"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tc&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;testcases&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c"&gt;// Use f.Add to provide a seed corpus&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fuzz&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;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&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;orig&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;rev&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Reverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;doubleRev&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Reverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rev&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;orig&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;doubleRev&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Before: %q, after: %q"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;doubleRev&lt;/span&gt;&lt;span class="p"&gt;)&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;utf8&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ValidString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;utf8&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ValidString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rev&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Reverse produced invalid UTF-8 string %q"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rev&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Il y a des différences de syntaxes par rapport aux tests classiques :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;La nom de la fonction débute par &lt;code&gt;FuzzXxx&lt;/code&gt; (à la place de &lt;code&gt;TestXxx)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;La fonction prend &lt;code&gt;*testing.F&lt;/code&gt; en type d'entrée (à la place de &lt;code&gt;*testing.T&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;On utilise &lt;code&gt;f.Fuzz&lt;/code&gt; (à la place de &lt;code&gt;t.Run&lt;/code&gt;) qui prend comme paramètre une fonction à &lt;em&gt;fuzzer&lt;/em&gt; qui a comme paramètres &lt;code&gt;*testing.T&lt;/code&gt; et le type à &lt;em&gt;fuzzer&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On peut ici identifier une limitation à ce type de test : il n’est pas possible de prédire la sortie puisque nous contrôlons pas l’entrée. Il faut donc s’appuyer sur d’autres propriétés pour réaliser nos tests, comme :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inverser deux fois l’entrée doit préserver l’entrée originale&lt;/li&gt;
&lt;li&gt;La chaîne inversée doit être une chaîne UTF-8 valide&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Aller plus loin
&lt;/h3&gt;

&lt;p&gt;Le &lt;a href="%5Bhttps://go.dev/doc/tutorial/fuzz%5D(https://go.dev/doc/tutorial/fuzz)"&gt;tutoriel de go.dev&lt;/a&gt; (dont sont tiré les exemples ci-dessus), ainsi que la &lt;a href="%5Bhttps://go.dev/doc/fuzz/%5D(https://go.dev/doc/fuzz/)"&gt;documentation officielle&lt;/a&gt; vous permettrons de creuser le sujet.&lt;/p&gt;

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

&lt;p&gt;Cette nouvelle fonctionnalité permet de simplifier le travail sur de multiples paquets interdépendant en même temps.&lt;/p&gt;

&lt;p&gt;Un &lt;em&gt;workspace&lt;/em&gt; est défini par un fichier &lt;code&gt;go.work&lt;/code&gt; de cette forme :&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;go&lt;/span&gt; &lt;span class="m"&gt;1.18&lt;/span&gt;

&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;../&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bar&lt;/span&gt;
  &lt;span class="o"&gt;./&lt;/span&gt;&lt;span class="n"&gt;baz&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;replace&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="m"&gt;.2.3&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bar&lt;/span&gt; &lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="m"&gt;.4.5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On peut alors initialiser un espace de travail dans le répertoire courant :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go work init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Aller plus loin
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="%5Bhttps://zerokspot.com/weblog/2022/01/14/workspaces-in-go118/%5D(https://zerokspot.com/weblog/2022/01/14/workspaces-in-go118/)"&gt;Workspaces in Go 1.18&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;La &lt;a href="https://pkg.go.dev/cmd/go@master#hdr-Workspace_maintenance"&gt;documentation officielle&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Une &lt;a href="https://www.youtube.com/watch?v=wQglU5aB5NQ"&gt;vidéo Youtube de Michael Matloob&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Autres ajouts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Amélioration des performances de 20% sur &lt;em&gt;Apple M1&lt;/em&gt;, &lt;em&gt;ARM64&lt;/em&gt;, &lt;em&gt;PowerPC64.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Le type &lt;code&gt;any&lt;/code&gt; comme alias de &lt;code&gt;interface{}&lt;/code&gt; : l’ &lt;a href="https://github.com/golang/go/issues/49884"&gt;&lt;code&gt;issue&lt;/code&gt;&lt;/a&gt; sur &lt;em&gt;Github&lt;/em&gt;,  un &lt;a href="https://blog.carlmjohnson.net/post/2022/golang-118-even-more-minor-features/"&gt;article de blog&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Un nouveau paquet &lt;code&gt;net/netip&lt;/code&gt; avec un type d’adresse IP : &lt;a href="https://pkg.go.dev/net/netip"&gt;documentation officielle&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Un paquet &lt;code&gt;debug/buildinfo&lt;/code&gt; pour accéder aux informations d’un binaire compilé : &lt;a href="https://pkg.go.dev/debug/buildinfo"&gt;documentation officielle&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pour conclure
&lt;/h3&gt;

&lt;p&gt;Voilà pour ce qui me paraît l’essentiel à savoir sur cette nouvelle version de Go. Vous trouverez l’intégralité des ajouts, des suppressions et des corrections dans la &lt;em&gt;&lt;a href="https://go.dev/doc/go1.18"&gt;Release Note&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Codez bien !&lt;/p&gt;

</description>
      <category>go</category>
      <category>french</category>
    </item>
    <item>
      <title>Programmation concurrente avec des goroutines</title>
      <dc:creator>Gwenaël NARDIN</dc:creator>
      <pubDate>Wed, 23 Mar 2022 11:50:16 +0000</pubDate>
      <link>https://dev.to/yeswearecoding/programmation-concurrente-avec-des-goroutines-3dj3</link>
      <guid>https://dev.to/yeswearecoding/programmation-concurrente-avec-des-goroutines-3dj3</guid>
      <description>&lt;p&gt;Nouvelle année, nouveau challenge ! Ca fait pas mal de temps de je lorgne sur le Go (ou Golang) et ça y est, il est venu le temps de s'y mettre !&lt;br&gt;
Avant cela, j'ai (un peu) mis à jour mon site et rajouter un lien pour ma page LinkedIn : n'hésitez pas à me suivre ou m'ajouter afin de recevoir les prochaines mises à jour 😊.&lt;/p&gt;

&lt;p&gt;Le Go (ou Golang) est un langage développé depuis quelques années désormais (plus de 10 ans) par une équipe de Google, et pas des débutants ! Notamment &lt;a href="https://fr.wikipedia.org/wiki/Brian_Kernighan"&gt;Brian Kernighan&lt;/a&gt;, éminent informaticien en C et autre. Ils ont alors développé ce langage pour simplifier l'utilisation du multithreading, principe au coeur du Go.&lt;/p&gt;

&lt;p&gt;Je vais vous présenter içi les &lt;code&gt;goroutines&lt;/code&gt;, principe de base pour la mise en oeuvre du multithreading en Go.&lt;/p&gt;
&lt;h2&gt;
  
  
  Définitions
&lt;/h2&gt;

&lt;p&gt;Programmation concurente : composition de plusieurs activités autonomes.&lt;/p&gt;

&lt;p&gt;Go supporte deux types de programmation concurrente :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CSP (&lt;em&gt;communicating sequential processes&lt;/em&gt; - processus séquentiels de communication). Les variables sont passées entre des activités indépendamment mais les variables sont la plus part du temps confinées à une seule de ces activités.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;shared memory multithreading&lt;/em&gt; (multithreading à mémoire partagée)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;goroutine : activité exécutée en concurrence&lt;/p&gt;
&lt;h2&gt;
  
  
  Exemples
&lt;/h2&gt;

&lt;p&gt;Maintenant que nous avons vu le principe de base, place aux exemples !&lt;/p&gt;
&lt;h3&gt;
  
  
  Basique
&lt;/h3&gt;

&lt;p&gt;On va faire un simple &lt;code&gt;hello world !&lt;/code&gt; mais en utilisant une &lt;code&gt;goroutine&lt;/code&gt;. On va écrire une fonction &lt;code&gt;say&lt;/code&gt; qui prend une &lt;code&gt;string&lt;/code&gt; en argument et que l'on appelera en tant que &lt;code&gt;goroutine&lt;/code&gt; (avec le mot-clé &lt;code&gt;go&lt;/code&gt;) et qui nous affichera "hello". Voyons ce que ça donne :&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="s"&gt;"fmt"&lt;/span&gt;


&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;say&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="kt"&gt;string&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;s&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;main&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;say&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello"&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;"world !"&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;La sortie :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;world &lt;span class="o"&gt;!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quoi ?!? Mais il manque un bout !!! 😱😱😱&lt;br&gt;&lt;br&gt;
Explication : la boucle principale &lt;code&gt;main&lt;/code&gt; n'attend pas la fin de l'exécution de la &lt;code&gt;goroutine&lt;/code&gt;. Pour le moment, on va résoudre ça avec un simple &lt;code&gt;sleep&lt;/code&gt;. On modifie le code ainsi :&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;"time"&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;say&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="kt"&gt;string&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;s&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;main&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;say&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello"&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;"world !"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;500&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Millisecond&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;On obtient en sortie :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;world &lt;span class="o"&gt;!&lt;/span&gt;
hello
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ah !!!!! Voilà ! On obtient bien ce que l'on souhaite en sortie mais c'est loin d'être optimal...&lt;/p&gt;

&lt;p&gt;On peut faire beaucoup mieux !! Place à la suite 😉&lt;/p&gt;

&lt;h3&gt;
  
  
  Attendre plusieurs goroutines
&lt;/h3&gt;

&lt;p&gt;Lorsque l'on a besoin d'attendre que une ou plusieurs &lt;code&gt;goroutine&lt;/code&gt; finissent, on utilise le packet &lt;code&gt;sync&lt;/code&gt; et la fonction &lt;a href="https://pkg.go.dev/sync#WaitGroup"&gt;sync.WaitGroup&lt;/a&gt;. Elle est utilisé pour bloquer le &lt;code&gt;main&lt;/code&gt; (ou toute autre fonction appelante) jusqu'à ce que toutes les &lt;code&gt;goroutine&lt;/code&gt; aient terminé leur travail. Un exemple parlant (adapté de l'article &lt;a href="https://goinbigdata.com/golang-wait-for-all-goroutines-to-finish/"&gt;How to wait for all goroutines to finish in Golang&lt;/a&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;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;"sync"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&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;worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wg&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WaitGroup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&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="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;//décrémentation (lorsque la goroutine a terminé)&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;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Worker %v: Début&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;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&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;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Worker %v: Terminé&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;id&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;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;wg&lt;/span&gt; &lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WaitGroup&lt;/span&gt; &lt;span class="c"&gt;// déclaration&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&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;"Main: Lancement du Worker"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&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="c"&gt;// incrémentation d'une unité&lt;/span&gt;
        &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;worker&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;wg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// passage par adresse&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;"Main: En attente des Workers"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Wait&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;"Main: Terminé"&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;Ce qui donne :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Main: Lancement &lt;span class="nb"&gt;du &lt;/span&gt;Worker 0
Main: Lancement &lt;span class="nb"&gt;du &lt;/span&gt;Worker 1
Main: Lancement &lt;span class="nb"&gt;du &lt;/span&gt;Worker 2
Main: Lancement &lt;span class="nb"&gt;du &lt;/span&gt;Worker 3
Main: Lancement &lt;span class="nb"&gt;du &lt;/span&gt;Worker 4
Worker 0: Début
Worker 4: Début
Worker 2: Début
Main: En attente des Workers
Worker 1: Début
Worker 3: Début
Worker 1: Terminé
Worker 0: Terminé
Worker 4: Terminé
Worker 2: Terminé
Worker 3: Terminé
Main: Terminé
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;N'est-ce pas formidable ?&lt;/p&gt;

&lt;p&gt;L'utilisation de &lt;code&gt;WaitGroup&lt;/code&gt; est assez simple :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;déclation dans le &lt;code&gt;main&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;incrémentation avec &lt;code&gt;.Add(1)&lt;/code&gt; avant l'appel de la &lt;code&gt;goroutine&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;appel de la &lt;code&gt;goroutine&lt;/code&gt; avec passage par adresse du &lt;code&gt;WaitGroup&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;décrémentation du &lt;code&gt;WaitGroup&lt;/code&gt; au sein de la goroutine avec &lt;code&gt;.Done()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;en fin de bloc, on attend la fin des &lt;code&gt;goroutine&lt;/code&gt; avec &lt;code&gt;.Wait()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notez l'utilisation de &lt;code&gt;defer&lt;/code&gt; pour la décrémentation dès le début de la &lt;code&gt;goroutine&lt;/code&gt;. Ce mot-clé permet de s'assurer que la fonction qui le suit sera bien appelée à la fin du bloc. On le retrouve pour la lecture des fichiers : on s'assure ainsi que ce dernier sera bien fermé à la fin du traitement.&lt;/p&gt;

&lt;h3&gt;
  
  
  goroutine anonyme
&lt;/h3&gt;

&lt;p&gt;Lorsque la &lt;code&gt;goroutine&lt;/code&gt; ne fait quelques lignes (pas trop, sinon le code devient vite illisible...), il est possible d'utiliser une fonction anonyme. Voyons avec l'exemple précédent ce que cela change :&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;"sync"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&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="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;wg&lt;/span&gt; &lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WaitGroup&lt;/span&gt; &lt;span class="c"&gt;// déclaration&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&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;"Main: Lancement du Worker"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&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="c"&gt;// incrémentation d'une unité&lt;/span&gt;

        &lt;span class="k"&gt;go&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;id&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;// fonction anonyme&lt;/span&gt;
            &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;//décrémentation (lorsque la goroutine a terminé)&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;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Worker %v: Début&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;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&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;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Worker %v: Terminé&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;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}(&lt;/span&gt;&lt;span class="n"&gt;i&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;"Main: En attente des Workers"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Wait&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;"Main: Terminé"&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;C'est un peu plus concis 😊&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Voilà, c'est terminé pour cette petite présentation ! J'ai utilisé également les livres suivant dans mon apprentissage :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://amzn.to/3gWR6By"&gt;The Go Programming Language&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.fr/Learning-Go-Idiomatic-Real-World-Programming/dp/1492077216/ref=sr_1_5?keywords=the+go+programming+language&amp;amp;qid=1648036042&amp;amp;s=books&amp;amp;sprefix=the+go+prog%252Cstripbooks%252C86&amp;amp;sr=1-5&amp;amp;_encoding=UTF8&amp;amp;tag=diveinembedded-21&amp;amp;linkCode=ur2&amp;amp;linkId=df86ad9e1cf41db68c6881a6421b83c5&amp;amp;camp=1642&amp;amp;creative=6746"&gt;Learning Go: An Idiomatic Approach to Real-World Go Programming&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A bientôt !&lt;/p&gt;

</description>
      <category>go</category>
      <category>french</category>
    </item>
  </channel>
</rss>
