<?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: Emre Odabas</title>
    <description>The latest articles on DEV Community by Emre Odabas (@emreodabas).</description>
    <link>https://dev.to/emreodabas</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%2F764681%2Ff0851706-bb80-4b57-b390-b5fc14552df5.png</url>
      <title>DEV Community: Emre Odabas</title>
      <link>https://dev.to/emreodabas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/emreodabas"/>
    <language>en</language>
    <item>
      <title>Kafka Exception C{r}onsumer 🔥 🚀</title>
      <dc:creator>Emre Odabas</dc:creator>
      <pubDate>Fri, 11 Nov 2022 12:29:31 +0000</pubDate>
      <link>https://dev.to/emreodabas/kafka-exception-cronsumer-3bhm</link>
      <guid>https://dev.to/emreodabas/kafka-exception-cronsumer-3bhm</guid>
      <description>&lt;p&gt;As a Trendyol Indexing Team, our architecture is heavily based on an event-based system that should be consistent, eventually. So even though this word seems to give relief, it is tough to ensure that every message in the system is successfully processed.&lt;/p&gt;

&lt;p&gt;Our eventing system relies on &lt;a href="https://kafka.apache.org/" rel="noopener noreferrer"&gt;Apache Kafka&lt;/a&gt;. It gives us powerful abilities when we need performance on event streaming. Our messages carry invalidations (daily 150M+) that should apply to Trendyol contents (300M+). This invalidation could be about a stock, promotion, or one of our 30 events.&lt;/p&gt;

&lt;p&gt;In events worlds, we need to orchestrate our messages even in some inconsistent states. Retrying and delaying messages are our key strategies in this “eventual” life cycle of events. We have 10+ consumers that should apply this strategy. Therefore, we created an open-sourced library called &lt;a href="https://github.com/Trendyol/kafka-cronsumer" rel="noopener noreferrer"&gt;Kafka Cronsumer&lt;/a&gt; for easy implementation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa1ykndrnvrhv2ojfnd2h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa1ykndrnvrhv2ojfnd2h.png" alt="Figure 1: Show me the code"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  How Kafka Cronsumer Works 💡
&lt;/h2&gt;

&lt;p&gt;As the library name suggests, it consumes events within the exception topic based on the given cron expression.&lt;/p&gt;

&lt;p&gt;For example, we could specify a cron expression as &lt;code&gt;*/20 * * * *&lt;/code&gt;, which means to run every 20th minutes. We could also set a &lt;code&gt;duration&lt;/code&gt; 15 minutes (15m) represents our exception consumer actively consuming events within this fixed duration.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the consumer gets an error when consuming a message, it increases the message retry count and produces the exception topic for handling the next iteration (next work time) again.&lt;/li&gt;
&lt;li&gt;A message is discarded or moved to a dead letter if it exceeds &lt;code&gt;maxRetry&lt;/code&gt; value.&lt;/li&gt;
&lt;li&gt;Each message is processed only once at every iteration. So if the consumer encounters a message produced after our consumer start time, it pauses and waits for the next iteration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As an overview, it works shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5hen0ib0cc2z4ymp2qtr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5hen0ib0cc2z4ymp2qtr.png" alt="Figure 2: Kafka Exception Cronsumer timeline overview"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  How to use it? 👈
&lt;/h2&gt;

&lt;p&gt;First of all, we need to set the required config values. We can also specify Kafka Consumer &amp;amp; Producer related configs, but it is not mandatory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;consumer:
  groupId: "exception-consumer"
  topic: "exception"
  maxRetry: 3
  concurrency: 1
  cron: "*/20 * * * *"
  duration: 15m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We define &lt;code&gt;consumeFn&lt;/code&gt; function, which describes how the exception messages are consumed.&lt;/p&gt;

&lt;p&gt;After that, we initialize Kafka cronsumer with these config values and &lt;code&gt;consumeFn&lt;/code&gt; and run. It starts to work as shown above in the how to Kafka Cronsumer works section.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func main() {
        // ..
    var consumeFn kafka.ConsumeFn = func(message kafka.Message) error {
        fmt.Printf("consumer &amp;gt; Message received: %s\n", string(message.Value))
        return nil
    }

    c := cronsumer.New(kafkaConfig, consumeFn)
    c.Run()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find a number of ready-to-run examples at &lt;a href="https://github.com/Trendyol/kafka-cronsumer/blob/main/examples" rel="noopener noreferrer"&gt;this directory&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  When to use it? 🤔
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Iteration-based back-off strategies are applicable&lt;/li&gt;
&lt;li&gt;Messages could be processed in an eventually consistent state&lt;/li&gt;
&lt;li&gt;Max retry exceeded messages could be ignored&lt;/li&gt;
&lt;li&gt;To increase consumer resiliency
-To increase consumer performance with concurrency&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  When to avoid?❗️
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Messages should be processed in order&lt;/li&gt;
&lt;li&gt;Messages should be certainly processed (we discard messages if max retry is exceeded)&lt;/li&gt;
&lt;li&gt;Messages should be committed (we use auto-commit interval for increasing performance)&lt;/li&gt;
&lt;li&gt;Messages with TTL (Time to Live)&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Thanks for reading this far. All feedbacks are welcome. We love to share our knowledge. If you like to “share” with us, you could apply for our &lt;a href="https://jobs.lever.co/trendyol?lever-via=q48u5LZ7k7" rel="noopener noreferrer"&gt;open positions&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Co-Authored by:&lt;br&gt;
&lt;a class="mentioned-user" href="https://dev.to/abdulsametileri"&gt;@abdulsametileri&lt;/a&gt; &lt;/p&gt;

</description>
      <category>go</category>
      <category>kafka</category>
      <category>cron</category>
    </item>
    <item>
      <title>Quick Guide: Go 1.19 Features</title>
      <dc:creator>Emre Odabas</dc:creator>
      <pubDate>Mon, 18 Jul 2022 14:55:15 +0000</pubDate>
      <link>https://dev.to/emreodabas/quick-guide-go-119-features-1j40</link>
      <guid>https://dev.to/emreodabas/quick-guide-go-119-features-1j40</guid>
      <description>&lt;p&gt;After the big bang of Go 1.18, Go still continues to develop new features. If you miss what comes with 1.18, check my previous &lt;a href="https://medium.com/@emreodabas_20110/quick-guide-go-1-18-features-e236d5b351ef"&gt;Quick Guide&lt;/a&gt;. For now, &lt;a href="https://groups.google.com/g/golang-announce/c/Lu8ODY19HhA"&gt;RC1&lt;/a&gt; has already been released and the version will be released in &lt;a href="https://tip.golang.org/doc/go1.19"&gt;August 2022&lt;/a&gt;. Let’s look at what comes with Go 1.19.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--d0qYPFij--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7j744r8g12roh11zgqpc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d0qYPFij--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7j744r8g12roh11zgqpc.png" alt="Gopher 1.19" width="880" height="1062"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Atomic Types&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Bool&lt;/code&gt;, &lt;code&gt;Int32&lt;/code&gt;,&lt;code&gt;Int64&lt;/code&gt;, &lt;code&gt;Uint32&lt;/code&gt;, &lt;code&gt;Uint64&lt;/code&gt;, &lt;code&gt;Uintptr&lt;/code&gt; and &lt;code&gt;Pointer&lt;/code&gt; are new atomic types under &lt;code&gt;sync/atomic&lt;/code&gt; package. If you are unfamiliar, we could summarize the atomic package that &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;provides low-level atomic memory primitives useful for implementing synchronization algorithms&lt;a href="https://pkg.go.dev/sync/atomic"&gt;*&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With these new types, we could use &lt;code&gt;Load&lt;/code&gt;,&lt;code&gt;Store&lt;/code&gt;, &lt;code&gt;Swap&lt;/code&gt;, &lt;code&gt;CompareAndSwap&lt;/code&gt; functions. TheAdd function is also could be used for numeric types. These functions simplify the code we &lt;a href="https://go.dev/play/p/4Trpfbd5jks"&gt;have written&lt;/a&gt; before Go 1.19, and you can check this new code on &lt;a href="https://go.dev/play/p/Iir_HEEMMLs?v=gotip"&gt;Go Playground&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xrwTXYBo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t1i6zgbj1bqzz6ettqq8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xrwTXYBo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t1i6zgbj1bqzz6ettqq8.png" alt="atomic-before-after" width="880" height="158"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Soft Memory Limit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As you may know, when it comes to tuning memory on Go, you have only one option to set &lt;code&gt;GOGC(runtime/debug.SetGCPercent)&lt;/code&gt;. Even though this optimization basically gives a tradeoff between CPU and memory, it does not respect users’ memory limit&lt;a href="https://github.com/golang/proposal/blob/150687b78c1d11cdb41572e75484c84280d5a963/design/48409/soft-memory-limit.src.md"&gt;**&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As described in the &lt;a href="https://github.com/golang/proposal/blob/150687b78c1d11cdb41572e75484c84280d5a963/design/48409/soft-memory-limit.src.md"&gt;proposal&lt;/a&gt;, we could define a soft memory limit with the &lt;code&gt;GOMEMLIMIT&lt;/code&gt; environment variable or &lt;code&gt;runtime/debug.SetMemoryLimitfunction&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With this new feature, we could decrease memory limits and define better memory utilization. It could be time to leave behind &lt;a href="https://blog.twitch.tv/en/2019/04/10/go-memory-ballast-how-i-learnt-to-stop-worrying-and-love-the-heap/"&gt;the memory ballast &lt;/a&gt;workaround the twitch team gave us🙏.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;New Functions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go 1.19 has several changes in &lt;a href="https://tip.golang.org/doc/go1.19"&gt;core libraries&lt;/a&gt;. When I checked those, I select some of them seems significant to me.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;fmt&lt;/code&gt; has new functions for appending data. &lt;code&gt;Append&lt;/code&gt;, &lt;code&gt;Appendf&lt;/code&gt; and &lt;code&gt;Appendln&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sort.Find&lt;/code&gt; is a &lt;a href="https://pkg.go.dev/sort@master#Find"&gt;new function&lt;/a&gt; for finding the smallest index of i with given comparator function. It &lt;a href="https://github.com/golang/go/issues/50340"&gt;offers&lt;/a&gt; better experience than &lt;code&gt;sort.Search&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Sorting algorithms switched to &lt;a href="https://arxiv.org/pdf/2106.05123.pdf"&gt;pattern-defeating quicksort&lt;/a&gt; for faster results for several scenarios.&lt;/li&gt;
&lt;li&gt;New &lt;code&gt;JoinPath&lt;/code&gt; function (&lt;code&gt;URL.JoinPath&lt;/code&gt; method) creates a new URL by joining a list of path elements.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6Vn0WiZI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d92hfd02v7xh07jmtzd3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6Vn0WiZI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d92hfd02v7xh07jmtzd3.png" alt="URL.JoinPath" width="880" height="89"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Unix build constraint&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;unix&lt;/code&gt; is a new build constraint that is satisfied if &lt;code&gt;GOOS&lt;/code&gt; is one of&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ios, linux, android, darwin, dragonfly, freebsd, hurd, illumos, netbsd, aix, openbsd or solaris&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;Compiler&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The compiler now uses a &lt;a href="https://en.wikipedia.org/wiki/Branch_table"&gt;jump table&lt;/a&gt; to implement large integer and string switch statements. Performance improvements for the switch statement vary but can be on the order of 20% faster. (&lt;code&gt;GOARCH=amd64&lt;/code&gt; and &lt;code&gt;GOARCH=arm64&lt;/code&gt; only)&lt;a href="https://tip.golang.org/doc/go1.19"&gt;***&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You could check this &lt;a href="https://github.com/benhoyt/goawk/issues/121"&gt;benchmark&lt;/a&gt; for details.&lt;/p&gt;




&lt;p&gt;With 1.19 version, the community works well and takes care of several performance optimizations. Many improvements and fixes will also be in this version. Those features are my selections. If I missed any fancy features, please contact me.&lt;/p&gt;

&lt;p&gt;If you like to join our Gophers, you could apply for our &lt;a href="https://jobs.lever.co/trendyol?lever-via=q48u5LZ7k7"&gt;open positions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Qo2KKVz---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n60uqgp9bde86pbdotco.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Qo2KKVz---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n60uqgp9bde86pbdotco.png" alt="source: https://www.clipartkey.com/view/wJbmTT_gopher-dropping-the-microphone-gopher-go/&amp;lt;br&amp;gt;
" width="880" height="952"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
    </item>
    <item>
      <title>Quick Guide: Go 1.18 Features
</title>
      <dc:creator>Emre Odabas</dc:creator>
      <pubDate>Fri, 10 Dec 2021 20:30:17 +0000</pubDate>
      <link>https://dev.to/emreodabas/quick-guide-go-118-features-e78</link>
      <guid>https://dev.to/emreodabas/quick-guide-go-118-features-e78</guid>
      <description>&lt;p&gt;With the Go 1.18 version, which is planned to be released in the first quarter of 2022, many new features are waiting for us.&lt;br&gt;
This version will be one of the most critical packages of Go history and we will reach the beta version probably in a month. So what are these changes?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6kieis7rcpbn4v4brlkq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6kieis7rcpbn4v4brlkq.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Type Parameters (Generics)
&lt;/h2&gt;

&lt;p&gt;The long-awaited "Type Parameter" feature in Go is actually known as Generics in some other languages. With this feature, we can give dynamic types to our functions. Let's dive into a simple example and write a function that finds the minimum value of any two int variables.&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;minInt&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="n"&gt;y&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&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;else&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we need the same functionality for float32, we need to rewrite the same thing also for float32.&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;minFloat&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;float32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="kt"&gt;float32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;float32&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;else&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the power of Type Parameters, we could easily define a function that could get desired types of variables. For defining types, we also encounter a new operator called &lt;code&gt;tilde ~&lt;/code&gt;. This operator actually returns us the interface of the type information, so we can make our type restrictions. Let's write the same min function that covers int and float32 types as below.&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;OrderTypes&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
   &lt;span class="err"&gt;~&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="err"&gt;~&lt;/span&gt;&lt;span class="kt"&gt;float32&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;min&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt; &lt;span class="n"&gt;OrderTypes&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;P&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;P&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;else&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It seems pretty solid, right? Go is also proposed a &lt;a href="https://github.com/golang/go/blob/master/src/constraints/constraints.go" rel="noopener noreferrer"&gt;constraints&lt;/a&gt; library that contains already defined type groups. For example, we could implement our function for all ordered types.&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;P&lt;/span&gt; &lt;span class="n"&gt;constraints&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Ordered&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;P&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;P&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;else&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, the use of generics is not limited to this sample. It could be very useful especially in ORM-style problems that we generally create functions that work with multiple types. As well, you could check these &lt;a href="https://github.com/golang/go/tree/dev.go2go/src/cmd/go2go/testdata/go2path/src" rel="noopener noreferrer"&gt;examples&lt;/a&gt; shared by the Go team also give you some ideas. If you desire to watch the details, there is a great &lt;a href="https://www.youtube.com/watch?v=KepBhuQJT9E" rel="noopener noreferrer"&gt;presentation&lt;/a&gt; the team made at GopherCon.&lt;br&gt;
Apart from these, the &lt;a href="https://gotipplay.golang.org/" rel="noopener noreferrer"&gt;online editor (playground)&lt;/a&gt; where we can experiment will also be useful. If you wish to try 1.18 in your own environment, you could download &lt;a href="https://pkg.go.dev/golang.org/dl/gotip" rel="noopener noreferrer"&gt;gotip&lt;/a&gt; and work with the active branch of Go.&lt;/p&gt;
&lt;h2&gt;
  
  
  Fuzzing Test
&lt;/h2&gt;

&lt;p&gt;With the Golang 1.18 package, the &lt;a href="https://go.dev/blog/fuzz-beta" rel="noopener noreferrer"&gt;"Fuzzing"&lt;/a&gt; feature will come into our lives. With this test library, which will be offered as beta, we will be able to automatically make random mutations of our inputs in unit tests.&lt;br&gt;
As software developers, we sometimes miss unit tests edge cases. And this lack of data diversity could be abused and used in security leaks and vulnerabilities especially on critical libraries. We could prevent this situation using Fuzzing Test.&lt;br&gt;
For implementing Fuzzing Test, you could wrap your unit tests with a method that name starts with the Fuzz prefix. You could also use the &lt;a href="https://pkg.go.dev/testing@master#hdr-Fuzzing" rel="noopener noreferrer"&gt;Go Testing&lt;/a&gt; page as a sample 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;func&lt;/span&gt; &lt;span class="n"&gt;FuzzHex&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="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;seed&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&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="p"&gt;{},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;0xa&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;0xf&lt;/span&gt;&lt;span class="p"&gt;},&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="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;}}&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;seed&lt;/span&gt;&lt;span class="p"&gt;)&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;in&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="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;enc&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;hex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EncodeToString&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;out&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;hex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DecodeString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;enc&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="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%v: decode: %v"&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;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;if&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;Equal&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;out&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;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%v: not equal after round trip: %v"&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;out&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;h2&gt;
  
  
  Workspaces
&lt;/h2&gt;

&lt;p&gt;This feature comes to facilitates developers' jobs, who work on multiple modules at the same time. Although the module version can be changed with the replace command in &lt;code&gt;go.mod&lt;/code&gt; version 1.17, it is often forgotten to clear these replace commands while committing the code. Inserting or removing that line every time is a very bothering thing to do for these developers.&lt;br&gt;
With the &lt;a href="https://go.googlesource.com/proposal/+/master/design/45713-workspace.md" rel="noopener noreferrer"&gt;Workspace&lt;/a&gt; feature, you could create a new file called &lt;code&gt;go.work&lt;/code&gt; and write the replace command there. This file allows us to change modules specific to our working environment without touching the existing &lt;code&gt;go.mod&lt;/code&gt; file. As an example, you could look at the property's proposed design page.&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.17&lt;/span&gt;

&lt;span class="n"&gt;directory&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;./&lt;/span&gt;&lt;span class="n"&gt;baz&lt;/span&gt; &lt;span class="c"&gt;// foo.org/bar/baz&lt;/span&gt;
    &lt;span class="o"&gt;./&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="c"&gt;// golang.org/x/tools&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;golang&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;x&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;=&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;fork&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;net&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;As a result, Go 1.18 comes with the useful Fuzzing and Workspaces features, along with the Generics feature that was &lt;a href="https://dzone.com/articles/go-doesnt-need-generics" rel="noopener noreferrer"&gt;discussed&lt;/a&gt;, &lt;a href="https://go.dev/blog/why-generics" rel="noopener noreferrer"&gt;talked&lt;/a&gt; and &lt;a href="https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md" rel="noopener noreferrer"&gt;introduced&lt;/a&gt; more than a year. Apart from that, many improvements and fixes will also be in this version. You can follow the status of the version and what it contains via this &lt;a href="https://github.com/golang/go/milestone/201" rel="noopener noreferrer"&gt;link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rknqqq4imacgnlkgh1y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rknqqq4imacgnlkgh1y.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Related links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.freecodecamp.org/news/generics-in-golang/" rel="noopener noreferrer"&gt; Generics in Go Explained with Code Examples &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://drgarcia1986.medium.com/playing-with-go-and-generics-bba6961b14a0" rel="noopener noreferrer"&gt; Playing with Go and Generics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lwn.net/Articles/829242/" rel="noopener noreferrer"&gt;Fuzzing in Go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://go.dev/doc/fuzz/" rel="noopener noreferrer"&gt;Go Fuzzing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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