<?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: charly3pins</title>
    <description>The latest articles on Forem by charly3pins (@charly3pins).</description>
    <link>https://forem.com/charly3pins</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%2F526747%2F86f612b6-fc5e-4fce-83ae-03d0d66e2475.jpg</url>
      <title>Forem: charly3pins</title>
      <link>https://forem.com/charly3pins</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/charly3pins"/>
    <language>en</language>
    <item>
      <title>Tech Gurus: Don’t Drink All the Kool-Aid</title>
      <dc:creator>charly3pins</dc:creator>
      <pubDate>Mon, 07 Apr 2025 17:35:11 +0000</pubDate>
      <link>https://forem.com/charly3pins/tech-gurus-dont-drink-all-the-kool-aid-3laj</link>
      <guid>https://forem.com/charly3pins/tech-gurus-dont-drink-all-the-kool-aid-3laj</guid>
      <description>&lt;p&gt;Tech’s got a guru problem—every time a new shiny toy pops up, cheap gurus sprout from under rocks like mushrooms.&lt;br&gt;
Suddenly, everyone’s an &lt;em&gt;expert&lt;/em&gt; in generative AI because they watched a YouTube tutorial.&lt;br&gt;
A few years back, it was crypto—everybody had a “system” to make you rich.&lt;br&gt;
Before that, cloud, big data, you name it. If it’s new, an army of instant prophets swears they’ve mastered it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spoiler: it’s dumb to buy that.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;How? If something’s been around for two minutes, nobody’s an expert—not you, not me, not the guy with 50k followers on X selling a shitty course.&lt;/p&gt;

&lt;p&gt;We’ve all seen job postings asking for X years of experience in tech that’s younger than the requirement itself.&lt;br&gt;
Take this gem from Sebastián Ramírez, the creator of FastAPI, a Python framework for building APIs:&lt;/p&gt;


&lt;blockquote&gt;
&lt;p&gt;I saw a job post the other day. 👔&lt;br&gt;&lt;br&gt;It required 4+ years of experience in FastAPI. 🤦&lt;br&gt;&lt;br&gt;I couldn’t apply as I only have 1.5+ years of experience since I created that thing. 😅&lt;br&gt;&lt;br&gt;Maybe it’s time to re-evaluate that "years of experience = skill level". ♻&lt;/p&gt;— Sebastián Ramírez (&lt;a class="mentioned-user" href="https://dev.to/tiangolo"&gt;@tiangolo&lt;/a&gt;) &lt;a href="https://twitter.com/tiangolo/status/1281946592459853830?ref_src=twsrc%5Etfw" rel="noopener noreferrer"&gt;July 11, 2020&lt;/a&gt;
&lt;/blockquote&gt;   

&lt;p&gt;It’s not a one-off—we’ve all gotten those weird vibes from recruiters or posts.&lt;br&gt;
But that’s a rant for another day.&lt;/p&gt;

&lt;p&gt;The real issue? A species that thrives on this chaos, emerging from the shadows as &lt;strong&gt;THE GURU&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  "The Guru"
&lt;/h2&gt;

&lt;p&gt;The sector’s exhausted—every hype wave drags in a flood of clowns with half-baked demos and “10x your life” promises.&lt;br&gt;
For folks too busy or lazy to question them, it’s an easy trap—follow the guru (in every sense), buy the hype, and then, not long after, realize it’s all smoke.&lt;br&gt;
The “expertise,” the swagger, the cred they built? Gone overnight.&lt;br&gt;
It’s their game, their hustle—but what about your business, your time, your sanity?&lt;br&gt;
That’s the cost of chasing self-proclaimed saviors, fake experts, wannabe gods.&lt;br&gt;
AI that writes flawless code, frameworks with no bugs, workflows that “just work”—blah, blah, blah.&lt;/p&gt;

&lt;p&gt;It’s noise, not signal. And the community’s fed up: we’re done chugging these jokers’ Kool-Aid just because they sound slick.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Spot Them
&lt;/h2&gt;

&lt;p&gt;It’s tricky—they latch onto what’s trending, riding the hype train with dummy examples, often without even testing the stuff they’re preaching.&lt;br&gt;
Sure, some are good at something—marketing, mostly.&lt;/p&gt;

&lt;p&gt;That’s why people bite: in a sea of lazy thinking, they don’t need to prove squat.&lt;br&gt;
They just say it, and the algorithm does the rest—oh, that sweet algorithm!&lt;br&gt;
They peddle “the solution” without knowing your mess—always in a controlled sandbox, no real-world grit.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Here’s the truth: it doesn’t work that way.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Be critical—test it yourself.&lt;br&gt;
Don’t trust a glossy stream demo; throw it into your terminal, your team, your chaos.&lt;br&gt;
If it can’t survive a sprint in your trenches, it’s junk.&lt;br&gt;
Cheap gurus crumble under real code—you won’t.&lt;/p&gt;

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

&lt;p&gt;If you’re still here, props—you’ve waded through my rant on these fakes.&lt;br&gt;
Tech’s too messy for their “expert” schtick.&lt;/p&gt;

&lt;p&gt;Got your own guru fatigue?&lt;br&gt;
Drop your thoughts on &lt;a href="https://www.linkedin.com/in/carlesfuste/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; or &lt;a href="https://x.com/charly3pins" rel="noopener noreferrer"&gt;Twitter/X&lt;/a&gt;, or subscribe to &lt;a href="https://techtrenches.substack.com/" rel="noopener noreferrer"&gt;Tech Trenches&lt;/a&gt; for more from the trenches.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

&lt;p&gt;{C3P}&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>leadership</category>
    </item>
    <item>
      <title>Vibe Coding: A Weekend Hack That's Not Ready for the Real World</title>
      <dc:creator>charly3pins</dc:creator>
      <pubDate>Tue, 01 Apr 2025 07:39:06 +0000</pubDate>
      <link>https://forem.com/charly3pins/vibe-coding-a-weekend-hack-thats-not-ready-for-the-real-world-9f2</link>
      <guid>https://forem.com/charly3pins/vibe-coding-a-weekend-hack-thats-not-ready-for-the-real-world-9f2</guid>
      <description>&lt;p&gt;Since Andrej Karpathy's tweet blew up in February 2025 —4 million views and counting— &lt;code&gt;vibe coding&lt;/code&gt; has been the tech world's shiny new toy.&lt;/p&gt;


&lt;blockquote&gt;
&lt;p&gt;There's a new kind of coding I call "vibe coding", where you fully give in to the vibes, embrace exponentials, and forget that the code even exists. It's possible because the LLMs (e.g. Cursor Composer w Sonnet) are getting too good. Also I just talk to Composer with SuperWhisper…&lt;/p&gt;— Andrej Karpathy (@karpathy) &lt;a href="https://twitter.com/karpathy/status/1886192184808149383?ref_src=twsrc%5Etfw" rel="noopener noreferrer"&gt;February 2, 2025&lt;/a&gt;
&lt;/blockquote&gt; 

&lt;p&gt;Tools like Cursor and SuperWhisper let you chat with AI, say "build me a game", and bam, you've got a prototype by Sunday night. &lt;br&gt;
It's a fun weekend hack, but it's nowhere near ready for the real world. Let's break it down.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's This "Vibe Coding" Hype?
&lt;/h2&gt;

&lt;p&gt;It's simple: you tell an AI your idea—"make a retro app" or "fix this messy UI" —and it churns out code while you chill.&lt;br&gt;
Karpathy's line, "see stuff, say stuff, run stuff, copy-paste stuff," sums it up. You feel like a coding wizard, slapping together apps in hours.&lt;br&gt;
I get the appeal—I've messed with it myself.&lt;br&gt;
But it's cool until you realize that AI doesn't care if it actually works tomorrow.&lt;br&gt;
That's where the cracks show.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I'm Calling BS on the Revolution
&lt;/h2&gt;

&lt;p&gt;I've led teams through enough production fires to know what holds up—and `vibe coding" doesn't. Here's why it's more hype than help:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It's a Mess Under the Hood&lt;/strong&gt;: The code looks fine until you dig in.
I've seen AI spit out stuff that's insecure—take Lovable's generated code, where sloppy handling of Supabase API keys left tokens exposed for anyone to snatch, ripe for abuse.
Good luck finding the bug when you didn't write it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Guessing Isn't Engineering&lt;/strong&gt;: You tweak until it "works", but that's not a system—it's a gamble. I've had to clean up worse disasters from less.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability? Nope&lt;/strong&gt;: That quick app is a nightmare to maintain. I once inherited a codebase so tangled it took weeks to unravel—AI-generated code feels like that on steroids.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You Get Lazy&lt;/strong&gt;: Lean on AI too much, and you're screwed when it flakes. The AI won't save you when the client calls at 2am.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prototypes Are Not Products
&lt;/h2&gt;

&lt;p&gt;The LinkedIn crowd loves saying "vibe coding" makes everyone a 10x engineer.&lt;br&gt;
Sure, for a prototype.&lt;br&gt;
But a prototype isn't a product, and a product isn't a business.&lt;br&gt;
This creates a shortcut culture that there is no benefit at all unless for the ones hyped with it.&lt;br&gt;
I've watched startups crash because they thought a weekend hack could scale.&lt;br&gt;
Real engineering—systems that don't buckle, teams that ship—takes depth, not vibes.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Advice: Play, Don't Pray
&lt;/h2&gt;

&lt;p&gt;If you're into &lt;code&gt;vibe coding&lt;/code&gt;, have fun—but keep it in the sandbox:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hack away on side projects or proofs-of-concept.&lt;/li&gt;
&lt;li&gt;Treat the output like a sketch—review it like your job's on the line.&lt;/li&gt;
&lt;li&gt;Don't even think about production without a real engineer's eyes on it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To be clear: I'm not anti-AI; I use it to brainstorm or speed up grunt work.&lt;br&gt;
But I'd rather trust my team and hard-earned skills than bet on a tool that's all flash, no substance.&lt;/p&gt;

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

&lt;p&gt;If you've made it this far, hats off—you've waded through my take on &lt;code&gt;vibe coding&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It's a slick gimmick for a quick prototype, but don't be fooled: it's nowhere near ready for the real stuff—solid systems and businesses need more than AI vibes.&lt;/p&gt;

&lt;p&gt;I've laid out why I think it's overhyped and risky, so if you've got a "vibe coding" win or wipeout, I'd love to hear it.&lt;/p&gt;

&lt;p&gt;Drop your thoughts on &lt;a href="https://www.linkedin.com/in/carlesfuste/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; or &lt;a href="https://x.com/charly3pins" rel="noopener noreferrer"&gt;Twitter/X&lt;/a&gt; or subscribe to &lt;a href="https://techtrenches.substack.com/" rel="noopener noreferrer"&gt;Tech Trenches&lt;/a&gt; for more from the trenches.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

&lt;p&gt;{C3P}&lt;/p&gt;

</description>
      <category>vibecoding</category>
      <category>softwareengineering</category>
      <category>ai</category>
    </item>
    <item>
      <title>My Neovim setup for Mac for coding (in Go), writing and boosting your productivity in 2024</title>
      <dc:creator>charly3pins</dc:creator>
      <pubDate>Fri, 02 Aug 2024 07:11:55 +0000</pubDate>
      <link>https://forem.com/charly3pins/my-neovim-setup-for-mac-for-coding-in-go-writing-and-boosting-your-productivity-in-2024-h8a</link>
      <guid>https://forem.com/charly3pins/my-neovim-setup-for-mac-for-coding-in-go-writing-and-boosting-your-productivity-in-2024-h8a</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I'm not going to lie, I tried to jump from my editor to Vim many times since I was using Eclipse, then Sublime and the latest VS Code.&lt;br&gt;
I have always been fascinated with Vim and its potential. How something so simple can be so powerful? The reality is that I started several times the Vimtutor and I got stuck.&lt;br&gt;
I tried to edit the text in Vim and I got stuck. I tried to code something and I got stuck. Last year I tried seriously and I spent one or two weeks just using Vim.&lt;br&gt;
I thought it was the moment, but I failed... again. In Q2 this year I decided to take that seriously. I read a lot of posts, watched a few YouTube videos and I also read&lt;br&gt;
&lt;a href="https://amzn.to/3Jaiqu0" rel="noopener noreferrer"&gt;Mastering Vim Quickly: From WTF to OMG in no time&lt;/a&gt; by &lt;em&gt;Jovica Ilic&lt;/em&gt;. Now yes! I am using Vim for almost anything. Sometimes I have to admit&lt;br&gt;
that I'm still using VS Code for tasks that require editing a lot of lines at the same time and I'm still not that good with Vim, but very little.&lt;/p&gt;

&lt;p&gt;So today I'm gonna show you my configuration of Neovim and all the plugins that I use every day while coding mainly.&lt;/p&gt;
&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;p&gt;I am using MacOS and I use brew for managing my dependencies, so I assume you will too, if not please install it by going to its &lt;a href="https://brew.sh/" rel="noopener noreferrer"&gt;official website&lt;/a&gt; and following the instructions.&lt;/p&gt;

&lt;p&gt;Is not mandatory but for the ones interested, I am using the &lt;a href="https://github.com/alacritty/alacritty" rel="noopener noreferrer"&gt;Alacritty terminal&lt;/a&gt;, so if you're interested you can download it using the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--cask&lt;/span&gt; alacritty
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I think I will publish a post in future when I explain all my terminal configurations, but let's go back to our Neovim setup.&lt;/p&gt;

&lt;p&gt;To install Neovim simply type this into your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;Neovim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  File structure
&lt;/h2&gt;

&lt;p&gt;From now on we will see the Neovim config. You can find the full code in my &lt;a href="https://github.com/charly3pins/dotfiles/tree/main/editors/nvim" rel="noopener noreferrer"&gt;dotfiles&lt;/a&gt;. Feel free to clone the repo and manipulate it as you want.&lt;/p&gt;

&lt;p&gt;The config will be stored in &lt;code&gt;~/.config/nvim&lt;/code&gt;. In my case, I have a symlink to my dotfiles repo as you probably noticed if you checked the repo, it's not required.&lt;/p&gt;

&lt;p&gt;If you don't have the folder created yet, you can do it running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/.config/nvim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then go inside that directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/.config/nvim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and create the main file for your config using lua as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;init.lua
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apart from the main file, I am going to create two folders, one for the core config and the other for the plugins config; and a lazy.lua file to manage the &lt;a href="https://github.com/folke/lazy.nvim" rel="noopener noreferrer"&gt;lazy.nvim&lt;/a&gt; plugin manager config.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; lua/charly3pins/core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; lua/charly3pins/plugins
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;lua/charly3pins/lazy.lua
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;charly3pins&lt;/code&gt; with your username.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core options
&lt;/h2&gt;

&lt;p&gt;For the core options, I have 3 files with different configs in each and 1 that bundles all 3. First of all, move to the core directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;lua/charly3pins/core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create the 4 files as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;autocommands.lua
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;init.lua
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;keymaps.lua
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;options.lua
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;autocommands&lt;/code&gt; I have the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-- Highlight when yanking (copying) text
--  Try it with `yap` in normal mode
--  See `:help vim.highlight.on_yank()`
vim.api.nvim_create_autocmd("TextYankPost", {
    desc = "Highlight when yanking (copying) text",
    group = vim.api.nvim_create_augroup("kickstart-highlight-yank", { clear = true }),
    callback = function()
        vim.highlight.on_yank()
    end,
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is used when yanking text to highlight what I yank.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;keymaps&lt;/code&gt; is where I define all my shortcuts. I use the space as the leader as the trigger and the config of the different plugins:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vim.g.mapleader = " "

local keymap = vim.keymap

-- use jk to exit insert mode
keymap.set("i", "jk", "&amp;lt;ESC&amp;gt;", { desc = "Exit insert mode with jk" })

-- clear search highlights
keymap.set("n", "&amp;lt;leader&amp;gt;nh", ":nohl&amp;lt;CR&amp;gt;", { desc = "Clear search highlights" })

-- delete single character without copying into register
-- keymap.set("n", "x", '"_x')

-- increment/decrement numbers
keymap.set("n", "&amp;lt;leader&amp;gt;+", "&amp;lt;C-a&amp;gt;", { desc = "Increment number" }) -- increment
keymap.set("n", "&amp;lt;leader&amp;gt;-", "&amp;lt;C-x&amp;gt;", { desc = "Decrement number" }) -- decrement

-- window management
keymap.set("n", "&amp;lt;leader&amp;gt;sv", "&amp;lt;C-w&amp;gt;v", { desc = "Split window vertically" }) -- split window vertically
keymap.set("n", "&amp;lt;leader&amp;gt;sh", "&amp;lt;C-w&amp;gt;s", { desc = "Split window horizontally" }) -- split window horizontally
keymap.set("n", "&amp;lt;leader&amp;gt;se", "&amp;lt;C-w&amp;gt;=", { desc = "Make splits equal size" }) -- make split windows equal width &amp;amp; height
keymap.set("n", "&amp;lt;leader&amp;gt;sq", "&amp;lt;cmd&amp;gt;close&amp;lt;CR&amp;gt;", { desc = "Close current split" }) -- close current split window

keymap.set("n", "&amp;lt;leader&amp;gt;to", "&amp;lt;cmd&amp;gt;tabnew&amp;lt;CR&amp;gt;", { desc = "Open new tab" }) -- open new tab
keymap.set("n", "&amp;lt;leader&amp;gt;tq", "&amp;lt;cmd&amp;gt;tabclose&amp;lt;CR&amp;gt;", { desc = "Close current tab" }) -- close current tab
keymap.set("n", "&amp;lt;leader&amp;gt;tn", "&amp;lt;cmd&amp;gt;tabn&amp;lt;CR&amp;gt;", { desc = "Go to next tab" }) --  go to next tab
keymap.set("n", "&amp;lt;leader&amp;gt;tp", "&amp;lt;cmd&amp;gt;tabp&amp;lt;CR&amp;gt;", { desc = "Go to previous tab" }) --  go to previous tab
keymap.set("n", "&amp;lt;leader&amp;gt;tf", "&amp;lt;cmd&amp;gt;tabnew %&amp;lt;CR&amp;gt;", { desc = "Open current buffer in new tab" }) --  move current buffer to new tab

-- Disable arrow keys in normal mode
vim.keymap.set("n", "&amp;lt;left&amp;gt;", '&amp;lt;cmd&amp;gt;echo "Use h to move!!"&amp;lt;CR&amp;gt;')
vim.keymap.set("n", "&amp;lt;right&amp;gt;", '&amp;lt;cmd&amp;gt;echo "Use l to move!!"&amp;lt;CR&amp;gt;')
vim.keymap.set("n", "&amp;lt;up&amp;gt;", '&amp;lt;cmd&amp;gt;echo "Use k to move!!"&amp;lt;CR&amp;gt;')
vim.keymap.set("n", "&amp;lt;down&amp;gt;", '&amp;lt;cmd&amp;gt;echo "Use j to move!!"&amp;lt;CR&amp;gt;')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;options&lt;/code&gt; are the vim options for the basic editor functionalities:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vim.cmd("let g:netrw_liststyle = 3")

local opt = vim.opt

-- line numbers
opt.relativenumber = true
opt.number = true

-- tabs &amp;amp; indentation
opt.tabstop = 2 -- 2 spaces for tabs
opt.shiftwidth = 2 -- 2 spaces for indent width
opt.expandtab = true -- expand tab to spaces
opt.autoindent = true -- copy indent from current line when starting new one

-- line wrapping
opt.wrap = false -- disable line wrapping

-- search settings
opt.ignorecase = true -- ignore case when searching
opt.smartcase = true -- if you include mixed case in your search, assumes you want case-sensitive

-- cursor line
opt.cursorline = true -- highlight the current cursor line

-- appearance

-- turn on termguicolors for nightfly colorscheme to work
-- (have to use iterm2 or any other true color terminal)
opt.termguicolors = true
opt.background = "dark" -- colorschemes that can be light or dark will be made dark
opt.signcolumn = "yes" -- show sign column so that text doesn't shift

-- backspace
opt.backspace = "indent,eol,start" -- allow backspace on indent, end of line or insert mode start position

-- clipboard
opt.clipboard:append("unnamedplus") -- use system clipboard as default register

-- split windows
opt.splitright = true -- split vertical window to the right
opt.splitbelow = true -- split horizontal window to the bottom
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Last the init file is where I bundle all of them as lua will execute the init first for each directory, so the content is simply this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require("charly3pins.core.options")
require("charly3pins.core.keymaps")
require("charly3pins.core.autocommands")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Lazy config
&lt;/h2&gt;

&lt;p&gt;As I said, I use lazy.nvim as the plugin manager for Neovim so the next step is to go up one directory and edit our &lt;code&gt;lazy.lua&lt;/code&gt; file to add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({
    "git",
    "clone",
    "--filter=blob:none",
    "https://github.com/folke/lazy.nvim.git",
    "--branch=stable", -- latest stable release
    lazypath,
  })
end
vim.opt.rtp:prepend(lazypath)

require("lazy").setup({ { import = "charly3pins.plugins" }, { import = "charly3pins.plugins.lsp" } }, {
    change_detection = {
        notify = false,
    }
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more details, you can find the documentation in the &lt;a href="https://github.com/folke/lazy.nvim" rel="noopener noreferrer"&gt;GitHub page&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap the initial config
&lt;/h2&gt;

&lt;p&gt;Once you have the core configuration files in place and the lazy.nvim config there is one step more you need to do before you can start playing around with the plugins.&lt;/p&gt;

&lt;p&gt;Go to the root folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ~/.config/nvim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and edit your &lt;code&gt;init.lua&lt;/code&gt; file and add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require("charly3pins.core")
require("charly3pins.lazy")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you just need to restart the terminal, and if you open again your Neovim, you will be able to type &lt;code&gt;:Lazy&lt;/code&gt; and see the plugin working.&lt;/p&gt;

&lt;p&gt;Your folder structure should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  lua
    charly3pins
      core
    │ │  autocommands.lua
    │ │  init.lua
    │ │  keymaps.lua
    │ └  options.lua
      plugins
    └  lazy.lua
   init.lua
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  My plugins
&lt;/h2&gt;

&lt;p&gt;Here I will share the list of all the plugins that I use and their configuration. For more details please refer to each documentation or ask me a question below.&lt;/p&gt;

&lt;p&gt;Each plugin needs to have a file with its name (the title in each section) .lua, like &lt;code&gt;alpha.lua&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  alpha
&lt;/h3&gt;

&lt;p&gt;A lua powered greeter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return {
  "goolord/alpha-nvim",
  event = "VimEnter",
  config = function()
    local alpha = require("alpha")
    local dashboard = require("alpha.themes.dashboard")

    -- Set header
    dashboard.section.header.val = {
      "                                                     ",
      "  ███╗   ██╗███████╗ ██████╗ ██╗   ██╗██╗███╗   ███╗ ",
      "  ████╗  ██║██╔════╝██╔═══██╗██║   ██║██║████╗ ████║ ",
      "  ██╔██╗ ██║█████╗  ██║   ██║██║   ██║██║██╔████╔██║ ",
      "  ██║╚██╗██║██╔══╝  ██║   ██║╚██╗ ██╔╝██║██║╚██╔╝██║ ",
      "  ██║ ╚████║███████╗╚██████╔╝ ╚████╔╝ ██║██║ ╚═╝ ██║ ",
      "  ╚═╝  ╚═══╝╚══════╝ ╚═════╝   ╚═══╝  ╚═╝╚═╝     ╚═╝ ",
      "                                                     ",
    }

    -- Set menu
    dashboard.section.buttons.val = {
      dashboard.button("e", "  &amp;gt; New File", "&amp;lt;cmd&amp;gt;ene&amp;lt;CR&amp;gt;"),
      dashboard.button("SPC ee", "  &amp;gt; Toggle file explorer", "&amp;lt;cmd&amp;gt;NvimTreeToggle&amp;lt;CR&amp;gt;"),
      dashboard.button("SPC ff", "󰱼 &amp;gt; Find File", "&amp;lt;cmd&amp;gt;Telescope find_files&amp;lt;CR&amp;gt;"),
      dashboard.button("SPC fs", "  &amp;gt; Find Word", "&amp;lt;cmd&amp;gt;Telescope live_grep&amp;lt;CR&amp;gt;"),
      dashboard.button("SPC wr", "󰁯  &amp;gt; Restore Session For Current Directory", "&amp;lt;cmd&amp;gt;SessionRestore&amp;lt;CR&amp;gt;"),
      dashboard.button("q", " &amp;gt; Quit NVIM", "&amp;lt;cmd&amp;gt;qa&amp;lt;CR&amp;gt;"),
    }

    -- Send config to alpha
    alpha.setup(dashboard.opts)

    -- Disable folding on alpha buffer
    vim.cmd([[autocmd FileType alpha setlocal nofoldenable]])
  end,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  auto-session
&lt;/h3&gt;

&lt;p&gt;A small automated session manager for Neovim.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return {
  "rmagatti/auto-session",
  config = function()
    local auto_session = require("auto-session")

    auto_session.setup({
      auto_restore_enabled = false,
      auto_session_suppress_dirs = { "~/", "~/Dev/", "~/Downloads", "~/Documents", "~/Desktop/" },
    })

    local keymap = vim.keymap

    keymap.set("n", "&amp;lt;leader&amp;gt;wr", "&amp;lt;cmd&amp;gt;SessionRestore&amp;lt;CR&amp;gt;", { desc = "Restore session for cwd" }) -- restore last workspace session for current directory
    keymap.set("n", "&amp;lt;leader&amp;gt;ws", "&amp;lt;cmd&amp;gt;SessionSave&amp;lt;CR&amp;gt;", { desc = "Save session for auto session root dir" }) -- save workspace session for current working directory
  end,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  bufferline
&lt;/h3&gt;

&lt;p&gt;A snazzy bufferline for Neovim.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return {
  "akinsho/bufferline.nvim",
  dependencies = { "nvim-tree/nvim-web-devicons" },
  version = "*",
  opts = {
    options = {
      mode = "tabs",
      separator_style = "slant",
    },
  },
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  colorscheme
&lt;/h3&gt;

&lt;p&gt;Scheme of colors for Neovim.&lt;br&gt;
I've been using the gruvbox for so long but I discovered a few weeks ago the craftzdog`s one and I am still using it, so I will share these 2 plus the tokyonight built by the one and only folke.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;nvim&lt;br&gt;
-- return {&lt;br&gt;
--  "ellisonleao/gruvbox.nvim",&lt;br&gt;
--  priority = 1000, -- make sure to load this before all the other start plugins&lt;br&gt;
--  config = function()&lt;br&gt;
--      vim.cmd("colorscheme gruvbox")&lt;br&gt;
--  end,&lt;br&gt;
-- }&lt;br&gt;
-- return {&lt;br&gt;
--  "folke/tokyonight.nvim",&lt;br&gt;
--  priority = 1000, -- Make sure to load this before all the other start plugins.&lt;br&gt;
--  init = function()&lt;br&gt;
--      -- Load the colorscheme here.&lt;br&gt;
--      -- Like many other themes, this one has different styles, and you could load&lt;br&gt;
--      -- any other, such as 'tokyonight-storm', 'tokyonight-moon', or 'tokyonight-day'.&lt;br&gt;
--      vim.cmd.colorscheme("tokyonight-night")&lt;br&gt;
--  end,&lt;br&gt;
-- }&lt;br&gt;
return {&lt;br&gt;
    "craftzdog/solarized-osaka.nvim",&lt;br&gt;
    lazy = false,&lt;br&gt;
    priority = 1000,&lt;br&gt;
    opts = {},&lt;br&gt;
    config = function()&lt;br&gt;
        vim.cmd("colorscheme solarized-osaka")&lt;br&gt;
    end,&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  comment
&lt;/h3&gt;

&lt;p&gt;Comment plugin for Neovim.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`nvim&lt;br&gt;
return {&lt;br&gt;
  "numToStr/Comment.nvim",&lt;br&gt;
  event = { "BufReadPre", "BufNewFile" },&lt;br&gt;
  dependencies = {&lt;br&gt;
    "JoosepAlviste/nvim-ts-context-commentstring",&lt;br&gt;
  },&lt;br&gt;
  config = function()&lt;br&gt;
    -- import comment plugin safely&lt;br&gt;
    local comment = require("Comment")&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;local ts_context_commentstring = require("ts_context_commentstring.integrations.comment_nvim")

-- enable comment
comment.setup({
  -- for commenting tsx, jsx, svelte, html files
  pre_hook = ts_context_commentstring.create_pre_hook(),
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;end,&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  dressing
&lt;/h3&gt;

&lt;p&gt;Neovim plugin to improve the default vim.ui interfaces.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;nvim&lt;br&gt;
return {&lt;br&gt;
  "stevearc/dressing.nvim",&lt;br&gt;
  event = "VeryLazy",&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  formatting
&lt;/h3&gt;

&lt;p&gt;Lightweight yet powerful formatter plugin for Neovim.&lt;/p&gt;

&lt;p&gt;Here I have the configuration for my most used programming languages like go, python and web development. Also for the config files like json and yaml and my writing in markdown.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`nvim&lt;br&gt;
return {&lt;br&gt;
    "stevearc/conform.nvim",&lt;br&gt;
    event = { "BufReadPre", "BufNewFile" },&lt;br&gt;
    config = function()&lt;br&gt;
        local conform = require("conform")&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    conform.setup({
        formatters_by_ft = {
            css = { "prettier" },
            html = { "prettier" },
            json = { "prettier" },
            yaml = { "prettier" },
            markdown = { "prettier" },
            lua = { "stylua" },
            python = { "isort", "black" },
            go = { "goimports", "gofmt" },
        },
        format_on_save = {
            lsp_fallback = true,
            async = false,
            timeout_ms = 1000,
        },
    })

    vim.keymap.set({ "n", "v" }, "&amp;lt;leader&amp;gt;cp", function()
        conform.format({
            lsp_fallback = true,
            async = false,
            timeout_ms = 1000,
        })
    end, { desc = "Format file or range (in visual mode)" })
end,
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  gitsigns
&lt;/h3&gt;

&lt;p&gt;Git integration for buffers.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`nvim&lt;br&gt;
return {&lt;br&gt;
  "lewis6991/gitsigns.nvim",&lt;br&gt;
  event = { "BufReadPre", "BufNewFile" },&lt;br&gt;
  opts = {&lt;br&gt;
    on_attach = function(bufnr)&lt;br&gt;
      local gs = package.loaded.gitsigns&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  local function map(mode, l, r, desc)
    vim.keymap.set(mode, l, r, { buffer = bufnr, desc = desc })
  end

  -- Navigation
  map("n", "]h", gs.next_hunk, "Next Hunk")
  map("n", "[h", gs.prev_hunk, "Prev Hunk")

  -- Actions
  map("n", "&amp;lt;leader&amp;gt;hs", gs.stage_hunk, "Stage hunk")
  map("n", "&amp;lt;leader&amp;gt;hr", gs.reset_hunk, "Reset hunk")
  map("v", "&amp;lt;leader&amp;gt;hs", function()
    gs.stage_hunk({ vim.fn.line("."), vim.fn.line("v") })
  end, "Stage hunk")
  map("v", "&amp;lt;leader&amp;gt;hr", function()
    gs.reset_hunk({ vim.fn.line("."), vim.fn.line("v") })
  end, "Reset hunk")

  map("n", "&amp;lt;leader&amp;gt;hS", gs.stage_buffer, "Stage buffer")
  map("n", "&amp;lt;leader&amp;gt;hR", gs.reset_buffer, "Reset buffer")

  map("n", "&amp;lt;leader&amp;gt;hu", gs.undo_stage_hunk, "Undo stage hunk")

  map("n", "&amp;lt;leader&amp;gt;hp", gs.preview_hunk, "Preview hunk")

  map("n", "&amp;lt;leader&amp;gt;hb", function()
    gs.blame_line({ full = true })
  end, "Blame line")
  map("n", "&amp;lt;leader&amp;gt;hB", gs.toggle_current_line_blame, "Toggle line blame")

  map("n", "&amp;lt;leader&amp;gt;hd", gs.diffthis, "Diff this")
  map("n", "&amp;lt;leader&amp;gt;hD", function()
    gs.diffthis("~")
  end, "Diff this ~")

  -- Text object
  map({ "o", "x" }, "ih", ":&amp;lt;C-U&amp;gt;Gitsigns select_hunk&amp;lt;CR&amp;gt;", "Gitsigns select hunk")
end,
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;},&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  indent-blankline
&lt;/h3&gt;

&lt;p&gt;Indent guides for Neovim.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;nvim&lt;br&gt;
return {&lt;br&gt;
  "lukas-reineke/indent-blankline.nvim",&lt;br&gt;
  event = { "BufReadPre", "BufNewFile" },&lt;br&gt;
  main = "ibl",&lt;br&gt;
  opts = {&lt;br&gt;
  --  indent = { char = "┊" },&lt;br&gt;
        indent = {&lt;br&gt;
            char = "│",&lt;br&gt;
            tab_char = "│",&lt;br&gt;
        },&lt;br&gt;
    }&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  init.lua
&lt;/h3&gt;

&lt;p&gt;As with other directories, this is not a plugin it's just the entry file that lua looks for in each directory.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;nvim&lt;br&gt;
return {&lt;br&gt;
  "nvim-lua/plenary.nvim", -- lua functions that many plugins use&lt;br&gt;
  "christoomey/vim-tmux-navigator", -- tmux &amp;amp; split window navigation&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  lazygit
&lt;/h3&gt;

&lt;p&gt;Plugin for calling lazygit from within Neovim.&lt;/p&gt;

&lt;p&gt;To make sure this works, install it using brew first:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;sh&lt;br&gt;
brew install jesseduffield/lazygit/lazygit&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;nvim&lt;br&gt;
return {&lt;br&gt;
  "kdheepak/lazygit.nvim",&lt;br&gt;
  cmd = {&lt;br&gt;
    "LazyGit",&lt;br&gt;
    "LazyGitConfig",&lt;br&gt;
    "LazyGitCurrentFile",&lt;br&gt;
    "LazyGitFilter",&lt;br&gt;
    "LazyGitFilterCurrentFile",&lt;br&gt;
  },&lt;br&gt;
  -- optional for floating window border decoration&lt;br&gt;
  dependencies = {&lt;br&gt;
    "nvim-lua/plenary.nvim",&lt;br&gt;
  },&lt;br&gt;
  -- setting the keybinding for LazyGit with 'keys' is recommended in&lt;br&gt;
  -- order to load the plugin when the command is run for the first time&lt;br&gt;
  keys = {&lt;br&gt;
    { "&amp;lt;leader&amp;gt;lg", "&amp;lt;cmd&amp;gt;LazyGit&amp;lt;cr&amp;gt;", desc = "Open lazy git" },&lt;br&gt;
  },&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  linting
&lt;/h3&gt;

&lt;p&gt;An asynchronous linter plugin for Neovim complementary to the built-in Language Server Protocol support.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`nvim&lt;br&gt;
return {&lt;br&gt;
  "mfussenegger/nvim-lint",&lt;br&gt;
  event = { "BufReadPre", "BufNewFile" },&lt;br&gt;
  config = function()&lt;br&gt;
    local lint = require("lint")&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lint.linters_by_ft = {
  go = { "golangcilint" },
  python = { "pylint" },
}

local lint_augroup = vim.api.nvim_create_augroup("lint", { clear = true })

vim.api.nvim_create_autocmd({ "BufEnter", "BufWritePost", "InsertLeave" }, {
  group = lint_augroup,
  callback = function()
    lint.try_lint()
  end,
})

vim.keymap.set("n", "&amp;lt;leader&amp;gt;l", function()
  lint.try_lint()
end, { desc = "Trigger linting for current file" })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;end,&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  lualine
&lt;/h3&gt;

&lt;p&gt;A blazing fast and easy to configure Neovim statusline plugin written in pure lua.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`nvim&lt;br&gt;
return {&lt;br&gt;
  "nvim-lualine/lualine.nvim",&lt;br&gt;
  dependencies = { "nvim-tree/nvim-web-devicons" },&lt;br&gt;
  config = function()&lt;br&gt;
    local lualine = require("lualine")&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;local colors = {
  blue = "#65D1FF",
  green = "#3EFFDC",
  violet = "#FF61EF",
  yellow = "#FFDA7B",
  red = "#FF4A4A",
  fg = "#c3ccdc",
  bg = "#112638",
  inactive_bg = "#2c3043",
}

local my_lualine_theme = {
  normal = {
    a = { bg = colors.blue, fg = colors.bg, gui = "bold" },
    b = { bg = colors.bg, fg = colors.fg },
    c = { bg = colors.bg, fg = colors.fg },
  },
  insert = {
    a = { bg = colors.green, fg = colors.bg, gui = "bold" },
    b = { bg = colors.bg, fg = colors.fg },
    c = { bg = colors.bg, fg = colors.fg },
  },
  visual = {
    a = { bg = colors.violet, fg = colors.bg, gui = "bold" },
    b = { bg = colors.bg, fg = colors.fg },
    c = { bg = colors.bg, fg = colors.fg },
  },
  command = {
    a = { bg = colors.yellow, fg = colors.bg, gui = "bold" },
    b = { bg = colors.bg, fg = colors.fg },
    c = { bg = colors.bg, fg = colors.fg },
  },
  replace = {
    a = { bg = colors.red, fg = colors.bg, gui = "bold" },
    b = { bg = colors.bg, fg = colors.fg },
    c = { bg = colors.bg, fg = colors.fg },
  },
  inactive = {
    a = { bg = colors.inactive_bg, fg = colors.semilightgray, gui = "bold" },
    b = { bg = colors.inactive_bg, fg = colors.semilightgray },
    c = { bg = colors.inactive_bg, fg = colors.semilightgray },
  },
}

-- configure lualine with modified theme
lualine.setup({
  options = {
    theme = my_lualine_theme,
  },
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;end,&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  markdown-preview
&lt;/h3&gt;

&lt;p&gt;Markdown preview plugin for Neovim.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`nvim&lt;br&gt;
return {&lt;br&gt;
    "iamcco/markdown-preview.nvim",&lt;br&gt;
    cmd = { "MarkdownPreviewToggle", "MarkdownPreview", "MarkdownPreviewStop" },&lt;br&gt;
    ft = { "markdown" },&lt;br&gt;
    build = function()&lt;br&gt;
        vim.fn&lt;a href=""&gt;"mkdp#util#install"&lt;/a&gt;&lt;br&gt;
    end,&lt;br&gt;
    config = function()&lt;br&gt;
        local keymap = vim.keymap&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    keymap.set("n", "&amp;lt;leader&amp;gt;mp", "&amp;lt;cmd&amp;gt;MarkdownPreview&amp;lt;cr&amp;gt;", { desc = "Markdown Preview" })
    keymap.set("n", "&amp;lt;leader&amp;gt;ms", "&amp;lt;cmd&amp;gt;MarkdownPreviewStop&amp;lt;cr&amp;gt;", { desc = "Markdown Preview Stop" })
    keymap.set("n", "&amp;lt;leader&amp;gt;mt", "&amp;lt;cmd&amp;gt;MarkdownPreviewToggle&amp;lt;cr&amp;gt;", { desc = "Markdown Preview Toggle" })
end,
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  mini
&lt;/h3&gt;

&lt;p&gt;Neovim Lua plugin to visualize and operate on indent scope. Part of 'mini.nvim' library.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;nvim&lt;br&gt;
return {&lt;br&gt;
    "echasnovski/mini.indentscope",&lt;br&gt;
    version = false,&lt;br&gt;
    opts = {&lt;br&gt;
        symbol  = "│",&lt;br&gt;
    },&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  nvim-cmp
&lt;/h3&gt;

&lt;p&gt;A completion plugin for Neovim coded in Lua.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`nvim&lt;br&gt;
return {&lt;br&gt;
  "hrsh7th/nvim-cmp",&lt;br&gt;
  event = "InsertEnter",&lt;br&gt;
  dependencies = {&lt;br&gt;
    "hrsh7th/cmp-buffer", -- source for text in buffer&lt;br&gt;
    "hrsh7th/cmp-path", -- source for file system paths&lt;br&gt;
    {&lt;br&gt;
      "L3MON4D3/LuaSnip",&lt;br&gt;
      -- follow latest release.&lt;br&gt;
      version = "v2.*", -- Replace  by the latest released major (first number of latest release)&lt;br&gt;
      -- install jsregexp (optional!).&lt;br&gt;
      build = "make install_jsregexp",&lt;br&gt;
    },&lt;br&gt;
    "saadparwaiz1/cmp_luasnip", -- for autocompletion&lt;br&gt;
    "rafamadriz/friendly-snippets", -- useful snippets&lt;br&gt;
    "onsails/lspkind.nvim", -- vs-code like pictograms&lt;br&gt;
  },&lt;br&gt;
  config = function()&lt;br&gt;
    local cmp = require("cmp")&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;local luasnip = require("luasnip")

local lspkind = require("lspkind")

-- loads vscode style snippets from installed plugins (e.g. friendly-snippets)
require("luasnip.loaders.from_vscode").lazy_load()

cmp.setup({
  completion = {
    completeopt = "menu,menuone,preview,noselect",
  },
  snippet = { -- configure how nvim-cmp interacts with snippet engine
    expand = function(args)
      luasnip.lsp_expand(args.body)
    end,
  },
  mapping = cmp.mapping.preset.insert({
    ["&amp;lt;C-k&amp;gt;"] = cmp.mapping.select_prev_item(), -- previous suggestion
    ["&amp;lt;C-j&amp;gt;"] = cmp.mapping.select_next_item(), -- next suggestion
    ["&amp;lt;C-b&amp;gt;"] = cmp.mapping.scroll_docs(-4),
    ["&amp;lt;C-f&amp;gt;"] = cmp.mapping.scroll_docs(4),
    ["&amp;lt;C-Space&amp;gt;"] = cmp.mapping.complete(), -- show completion suggestions
    ["&amp;lt;C-e&amp;gt;"] = cmp.mapping.abort(), -- close completion window
    ["&amp;lt;CR&amp;gt;"] = cmp.mapping.confirm({ select = false }),
  }),
  -- sources for autocompletion
  sources = cmp.config.sources({
            { name = "nvim_lsp" }, -- lsp
    { name = "luasnip" }, -- snippets
    { name = "buffer" }, -- text within current buffer
    { name = "path" }, -- file system paths
  }),

  -- configure lspkind for vs-code like pictograms in completion menu
  formatting = {
    format = lspkind.cmp_format({
      maxwidth = 50,
      ellipsis_char = "...",
    }),
  },
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;end,&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  nvim-tree
&lt;/h3&gt;

&lt;p&gt;A file explorer tree for Neovim written in lua.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`nvim&lt;br&gt;
return {&lt;br&gt;
  "nvim-tree/nvim-tree.lua",&lt;br&gt;
  dependencies = "nvim-tree/nvim-web-devicons",&lt;br&gt;
  config = function()&lt;br&gt;
    local nvimtree = require("nvim-tree")&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-- recommended settings from nvim-tree documentation
vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1

nvimtree.setup({
  view = {
    width = 35,
    relativenumber = true,
  },
  -- change folder arrow icons
  renderer = {
    indent_markers = {
      enable = true,
    },
    icons = {
      glyphs = {
        folder = {
          arrow_closed = "", -- arrow when folder is closed
          arrow_open = "", -- arrow when folder is open
        },
      },
    },
  },
  -- disable window_picker for
  -- explorer to work well with
  -- window splits
  actions = {
    open_file = {
      window_picker = {
        enable = false,
      },
    },
  },
  filters = {
    custom = { ".DS_Store" },
  },
  git = {
    ignore = false,
  },
})

-- set keymaps
local keymap = vim.keymap

keymap.set("n", "&amp;lt;leader&amp;gt;ee", "&amp;lt;cmd&amp;gt;NvimTreeToggle&amp;lt;CR&amp;gt;", { desc = "Toggle file explorer" }) -- toggle file explorer
keymap.set("n", "&amp;lt;leader&amp;gt;ef", "&amp;lt;cmd&amp;gt;NvimTreeFindFileToggle&amp;lt;CR&amp;gt;", { desc = "Toggle file explorer on current file" }) -- toggle file explorer on current file
keymap.set("n", "&amp;lt;leader&amp;gt;ec", "&amp;lt;cmd&amp;gt;NvimTreeCollapse&amp;lt;CR&amp;gt;", { desc = "Collapse file explorer" }) -- collapse file explorer
keymap.set("n", "&amp;lt;leader&amp;gt;er", "&amp;lt;cmd&amp;gt;NvimTreeRefresh&amp;lt;CR&amp;gt;", { desc = "Refresh file explorer" }) -- refresh file explorer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;end&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  surround
&lt;/h3&gt;

&lt;p&gt;Add/change/delete surrounding delimiter pairs with ease.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;nvim&lt;br&gt;
return {&lt;br&gt;
  "kylechui/nvim-surround",&lt;br&gt;
  event = { "BufReadPre", "BufNewFile" },&lt;br&gt;
  version = "*", -- Use for stability; omit to use&lt;/code&gt;main&lt;code&gt;branch for the latest features&lt;br&gt;
  config = true,&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  telescope
&lt;/h3&gt;

&lt;p&gt;A fuzzy finder over lists offering the following options: Find, Filter, Preview, Pick.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`nvim&lt;br&gt;
return {&lt;br&gt;
  "nvim-telescope/telescope.nvim",&lt;br&gt;
  branch = "0.1.x",&lt;br&gt;
  dependencies = {&lt;br&gt;
    "nvim-lua/plenary.nvim",&lt;br&gt;
    { "nvim-telescope/telescope-fzf-native.nvim", build = "make" },&lt;br&gt;
    "nvim-tree/nvim-web-devicons",&lt;br&gt;
  },&lt;br&gt;
  config = function()&lt;br&gt;
    local telescope = require("telescope")&lt;br&gt;
    local actions = require("telescope.actions")&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;telescope.setup({
  defaults = {
    path_display = { "smart" },
    mappings = {
      i = {
        ["&amp;lt;C-k&amp;gt;"] = actions.move_selection_previous, -- move to prev result
        ["&amp;lt;C-j&amp;gt;"] = actions.move_selection_next, -- move to next result
        ["&amp;lt;C-q&amp;gt;"] = actions.send_selected_to_qflist + actions.open_qflist, -- send selected items to quickfix list
      },
    },
  },
})

telescope.load_extension("fzf")

-- set keymaps
local keymap = vim.keymap

keymap.set("n", "&amp;lt;leader&amp;gt;ff", "&amp;lt;cmd&amp;gt;Telescope find_files&amp;lt;cr&amp;gt;", { desc = "Fuzzy find files in cwd" })
keymap.set("n", "&amp;lt;leader&amp;gt;fr", "&amp;lt;cmd&amp;gt;Telescope oldfiles&amp;lt;cr&amp;gt;", { desc = "Fuzzy find recent files" })
keymap.set("n", "&amp;lt;leader&amp;gt;fs", "&amp;lt;cmd&amp;gt;Telescope live_grep&amp;lt;cr&amp;gt;", { desc = "Find string in cwd" })
keymap.set("n", "&amp;lt;leader&amp;gt;fc", "&amp;lt;cmd&amp;gt;Telescope grep_string&amp;lt;cr&amp;gt;", { desc = "Find string under cursor in cwd" })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;end,&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  todo-comments
&lt;/h3&gt;

&lt;p&gt;Highlight, list and search todo comments in your projects.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`nvim&lt;br&gt;
return {&lt;br&gt;
  "folke/todo-comments.nvim",&lt;br&gt;
  event = { "BufReadPre", "BufNewFile" },&lt;br&gt;
  dependencies = { "nvim-lua/plenary.nvim" },&lt;br&gt;
  config = function()&lt;br&gt;
    local todo_comments = require("todo-comments")&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-- set keymaps
local keymap = vim.keymap -- for conciseness

keymap.set("n", "]t", function()
  todo_comments.jump_next()
end, { desc = "Next todo comment" })

keymap.set("n", "[t", function()
  todo_comments.jump_prev()
end, { desc = "Previous todo comment" })

todo_comments.setup()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;end,&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  treesitter
&lt;/h3&gt;

&lt;p&gt;Highlighting plugin.&lt;/p&gt;

&lt;p&gt;Here are my most used languages as before with an extra config for using with &lt;a href="https://github.com/a-h/templ" rel="noopener noreferrer"&gt;templ&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`nvim&lt;br&gt;
return {&lt;br&gt;
    "nvim-treesitter/nvim-treesitter",&lt;br&gt;
    event = { "BufReadPre", "BufNewFile" },&lt;br&gt;
    build = ":TSUpdate",&lt;br&gt;
    dependencies = {&lt;br&gt;
        "windwp/nvim-ts-autotag",&lt;br&gt;
        "vrischmann/tree-sitter-templ",&lt;br&gt;
    },&lt;br&gt;
    config = function()&lt;br&gt;
        vim.treesitter.language.register("templ", "templ")&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    local treesitter = require("nvim-treesitter.configs")

    -- configure treesitter
    treesitter.setup({
        highlight = {
            enable = true,
        },
        indent = { enable = true },
        autotag = {
            enable = true,
        },
        ensure_installed = {
            "json",
            "yaml",
            "html",
            "css",
            "go",
            "templ",
            "markdown",
            "markdown_inline",
            "bash",
            "lua",
            "vim",
            "dockerfile",
            "gitignore",
            "query",
            "vimdoc",
            "dart",
            "python",
        },
        incremental_selection = {
            enable = true,
            keymaps = {
                init_selection = "&amp;lt;C-space&amp;gt;",
                node_incremental = "&amp;lt;C-space&amp;gt;",
                scope_incremental = false,
                node_decremental = "&amp;lt;bs&amp;gt;",
            },
        },
    })
end,
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  trouble
&lt;/h3&gt;

&lt;p&gt;A pretty diagnostics, references, telescope results, quickfix and location list to help you solve all the trouble your code is causing.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;nvim&lt;br&gt;
return {&lt;br&gt;
  "folke/trouble.nvim",&lt;br&gt;
  dependencies = { "nvim-tree/nvim-web-devicons", "folke/todo-comments.nvim" },&lt;br&gt;
  keys = {&lt;br&gt;
    { "&amp;lt;leader&amp;gt;xx", "&amp;lt;cmd&amp;gt;TroubleToggle&amp;lt;CR&amp;gt;", desc = "Open/close trouble list" },&lt;br&gt;
    { "&amp;lt;leader&amp;gt;xw", "&amp;lt;cmd&amp;gt;TroubleToggle workspace_diagnostics&amp;lt;CR&amp;gt;", desc = "Open trouble workspace diagnostics" },&lt;br&gt;
    { "&amp;lt;leader&amp;gt;xd", "&amp;lt;cmd&amp;gt;TroubleToggle document_diagnostics&amp;lt;CR&amp;gt;", desc = "Open trouble document diagnostics" },&lt;br&gt;
    { "&amp;lt;leader&amp;gt;xq", "&amp;lt;cmd&amp;gt;TroubleToggle quickfix&amp;lt;CR&amp;gt;", desc = "Open trouble quickfix list" },&lt;br&gt;
    { "&amp;lt;leader&amp;gt;xl", "&amp;lt;cmd&amp;gt;TroubleToggle loclist&amp;lt;CR&amp;gt;", desc = "Open trouble location list" },&lt;br&gt;
    { "&amp;lt;leader&amp;gt;xt", "&amp;lt;cmd&amp;gt;TodoTrouble&amp;lt;CR&amp;gt;", desc = "Open todos in trouble" },&lt;br&gt;
  },&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  vim-maximizer
&lt;/h3&gt;

&lt;p&gt;Maximizes and restores the current window in Vim.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;nvim&lt;br&gt;
return {&lt;br&gt;
  "szw/vim-maximizer",&lt;br&gt;
  keys = {&lt;br&gt;
    { "&amp;lt;leader&amp;gt;sm", "&amp;lt;cmd&amp;gt;MaximizerToggle&amp;lt;CR&amp;gt;", desc = "Maximize/minimize a split" },&lt;br&gt;
  },&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  which-key
&lt;/h3&gt;

&lt;p&gt;Helps you remember your Neovim keymaps, by showing available keybindings in a popup as you type.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;nvim&lt;br&gt;
return {&lt;br&gt;
  "folke/which-key.nvim",&lt;br&gt;
  event = "VeryLazy",&lt;br&gt;
  init = function()&lt;br&gt;
    vim.o.timeout = true&lt;br&gt;
    vim.o.timeoutlen = 500&lt;br&gt;
  end,&lt;br&gt;
  opts = {},&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

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

&lt;p&gt;If you got here, congratulations because the list, as you can see, is quite extensive.&lt;/p&gt;

&lt;p&gt;As you probably know, the list of plugins for Neovim is tremendously huge and sometimes it can make us anxious and generate doubts about how we can start and which plugins can help us.&lt;/p&gt;

&lt;p&gt;I hope that with this list of mine and the ready-to-use configuration that I have left you, you can have a starting point and start creating your own editor to your liking little by little until you reach the perfect configuration for you.&lt;/p&gt;

&lt;p&gt;If you have plugins that you have not seen on my list that you think are interesting for me to try, please share them with me since I always like to discover and try new things, I would really appreciate it.&lt;/p&gt;

&lt;p&gt;I hope everything that I have tried to explain in this post has been clear, and please if there is any part that has not been completely clear or there are parts that I have not covered that you would like me to do, leave me a comment right here or through my social networks that you have on my profile and I will be happy to respond.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

&lt;p&gt;{C3P}&lt;/p&gt;

</description>
      <category>go</category>
      <category>neovim</category>
      <category>vim</category>
    </item>
    <item>
      <title>Maps in Go</title>
      <dc:creator>charly3pins</dc:creator>
      <pubDate>Mon, 22 Jul 2024 12:48:57 +0000</pubDate>
      <link>https://forem.com/charly3pins/maps-in-go-5a3j</link>
      <guid>https://forem.com/charly3pins/maps-in-go-5a3j</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Go incorporates a native type that implements hash tables called map. It is a data type made up of a collection of unique keys and a collection of values for each of those keys.&lt;br&gt;
It can be compared to a dictionary in other languages, for example, which stores key-value pairs. These values are accessed using keys, in the same way as arrays and slices as we saw in the previous post.&lt;br&gt;
The indexes are not limited to a number as in arrays or slices and the elements are not ordered, so if we print a map it will return a random order, if we do nothing to override its printing and force the desired order.&lt;/p&gt;
&lt;h2&gt;
  
  
  Map declaration and initialization
&lt;/h2&gt;

&lt;p&gt;To declare a map it is done with &lt;code&gt;map[key]value&lt;/code&gt;, where key will be the type we want our key to be (it must be of a comparable type &lt;a href="https://go.dev/ref/spec#Comparison_operators" rel="noopener noreferrer"&gt;https://go.dev/ref/spec#Comparison_operators&lt;/a&gt;) and value will be the type that we want the map to be stored in each of the keys, whatever type it is, from an int to a struct, or another map, whatever we want.&lt;/p&gt;

&lt;p&gt;As with slices, maps are referenced types, which means that the zero value of a map will be nil.&lt;br&gt;
This happens because underneath it there is a hash table which stores the keys and values, and they are simply an envelope, abstraction, of them.&lt;/p&gt;

&lt;p&gt;If we declare it as:&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;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;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;its value will be nil.&lt;/p&gt;

&lt;p&gt;If we want it to have a zero value, we can use the declaration:&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;m&lt;/span&gt; &lt;span class="o"&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;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we can even initialize it just like the slices, using the &lt;code&gt;make&lt;/code&gt; function.&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;m&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&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="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Doing this will initialize a hash map with the appropriate memory pool for it, thus returning a map that points to that data structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding and reading values from a map
&lt;/h2&gt;

&lt;p&gt;Adding values to a map is done by using curly braces &lt;code&gt;[]&lt;/code&gt; and the curly brace, just like with arrays or slices. In this example we will create a map with the keys being strings and the values being integers, to store names and ages.&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;ages&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&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="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;33&lt;/span&gt;
&lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Charly"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;27&lt;/span&gt;
&lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Jenny"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;45&lt;/span&gt;
&lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Lisa"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;19&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we want to add the values to it when we declare the map, we can use the short declaration and do it all in the same step:&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;ages&lt;/span&gt; &lt;span class="o"&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="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"John"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;33&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Charly"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;27&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Jenny"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Lisa"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;19&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To read the values, we simply have to indicate the key to our map and it will return that value. For example, to find out Lisa's age, we can do:&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;ages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Lisa"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c"&gt;// 19&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we try to access a key that does not exist, the value obtained will be the zero value of the type, in this case it would be "", since it is a string.&lt;/p&gt;

&lt;p&gt;In order to check if an element exists in the map, we can check if the type is the default, but it is not very reliable, since perhaps it exists but its value is an empty string or 0 in the case of int, which would match with its zero value, so Go helps us with the following:&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;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Randy"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we equal the map to two values, the first will be the value of that element accessed through the key, in this case "Randy" which does not exist, and the second will be a boolean, which will indicate whether it exists or not.&lt;/p&gt;

&lt;p&gt;If we are not interested in the value and simply want to check for the existence of a key, we can use &lt;code&gt;_&lt;/code&gt; to ignore the value as follows:&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;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Randy"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As with arrays and slices, we can use the &lt;code&gt;len&lt;/code&gt; function to find out how many elements there are in the map.&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="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c"&gt;// 4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we want to modify a value, it is as simple as accessing said value using a key and matching it with another, and it will be modified.&lt;/p&gt;

&lt;p&gt;If we declare a second map pointing to the first, if we modify the value of the second, since it is a referenced type, we will be modifying the value of the first, because both share the same hash table underneath.&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;ages&lt;/span&gt; &lt;span class="o"&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="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"John"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;33&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Charly"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;27&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Jenny"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Lisa"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;19&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;agesNew&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ages&lt;/span&gt;
&lt;span class="n"&gt;agesNew&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Bryan"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;77&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;agesNew&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// map[Bryan:77 Charly:27 Jenny:45 John:33 Lisa:19]&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;ages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// map[Bryan:77 Charly:27 Jenny:45 John:33 Lisa:19]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Removing values from a map
&lt;/h2&gt;

&lt;p&gt;To delete elements from a map, Go provides us with a delete function with the following signature &lt;code&gt;delete(m map[Type]Type1, key Type)&lt;/code&gt; which receives a map and the key to be deleted.&lt;br&gt;
In the previous case, if we wanted to eliminate "Lisa" we would do it:&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="nb"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Lisa"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Looping through maps
&lt;/h2&gt;

&lt;p&gt;If we want to go through the content of a map, we can do it using a &lt;code&gt;for&lt;/code&gt; with the variation of &lt;code&gt;range&lt;/code&gt; that we already saw in the post on arrays and slices.&lt;br&gt;
As then, the first element will be the index, therefore the key, and the second the value.&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;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&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;ages&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;"%s: %d&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;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Output:&lt;/span&gt;
&lt;span class="c"&gt;// Jenny: 45&lt;/span&gt;
&lt;span class="c"&gt;// Lisa: 19&lt;/span&gt;
&lt;span class="c"&gt;// John: 33&lt;/span&gt;
&lt;span class="c"&gt;// Charly: 27&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As with arrays and slices, if we are only interested in the value, without the key, we can omit it by using &lt;code&gt;_&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;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;value&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;ages&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;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Output:&lt;/span&gt;
&lt;span class="c"&gt;// 19&lt;/span&gt;
&lt;span class="c"&gt;// 33&lt;/span&gt;
&lt;span class="c"&gt;// 27&lt;/span&gt;
&lt;span class="c"&gt;// 45&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And if what interests us is simply the key, we can assign the range to a single variable to obtain it:&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;for&lt;/span&gt; &lt;span class="n"&gt;key&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;ages&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;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Output:&lt;/span&gt;
&lt;span class="c"&gt;// John&lt;/span&gt;
&lt;span class="c"&gt;// Charly&lt;/span&gt;
&lt;span class="c"&gt;// Jenny&lt;/span&gt;
&lt;span class="c"&gt;// Lisa&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Sort a map
&lt;/h2&gt;

&lt;p&gt;As I mentioned in the introduction, in a map the information is not ordered, so when looping through it we cannot specify what order it follows, nor can Go guarantee that the order between executions is the same.&lt;br&gt;
As we saw with arrays and slices, in the standard library there is a &lt;code&gt;sort&lt;/code&gt; package which helps us sort elements: &lt;a href="https://pkg.go.dev/sort" rel="noopener noreferrer"&gt;https://pkg.go.dev/sort&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Following our example with &lt;code&gt;ages&lt;/code&gt; and using &lt;code&gt;sort&lt;/code&gt;, we can sort the keys of the map before traversing it and thus guarantee that it will be accessed in order.&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;ages&lt;/span&gt; &lt;span class="o"&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="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"John"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;33&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Charly"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;27&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Jenny"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Lisa"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;19&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;keys&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&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="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;ages&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;k&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;ages&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keys&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="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Strings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keys&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;k&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;keys&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;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ages&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="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Output:&lt;/span&gt;
&lt;span class="c"&gt;// Charly 27&lt;/span&gt;
&lt;span class="c"&gt;// Jenny 45&lt;/span&gt;
&lt;span class="c"&gt;// John 33&lt;/span&gt;
&lt;span class="c"&gt;// Lisa 19&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We declare our &lt;code&gt;ages&lt;/code&gt; map with the short declaration as we saw before.&lt;br&gt;
We create a string slices to store the keys and use the make method with 0 length, since we do not have any keys at the moment, but we do reserve the capacity it will have using the &lt;code&gt;len&lt;/code&gt; method for the length of our map.&lt;br&gt;
We go through the &lt;code&gt;ages&lt;/code&gt; map to keep its keys and add them to the created slice.&lt;br&gt;
We sort the keys alphabetically with the &lt;code&gt;sort.Strings&lt;/code&gt; function.&lt;br&gt;
We go through the slice of keys, already ordered, and access the map with the key in question.&lt;br&gt;
This way we will access the map in an orderly manner and we can do the logic that our program needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problems with Concurrency
&lt;/h2&gt;

&lt;p&gt;Something to keep in mind with maps is that they are not safe to use concurrently. If these are concurrent reads, either accessing a value or through a for with a range, there is no problem with multiple goroutines accessing it at the same time.&lt;br&gt;
The problematic case is when you want to update the value of a map concurrently, either by adding or removing elements from it, and at the same time you are reading it from another side, for example.&lt;br&gt;
To solve this situation there are several possible solutions, which I will not go into much detail, I will simply mention and leave it to your choice to delve deeper into them.&lt;/p&gt;

&lt;p&gt;If we use the &lt;code&gt;sync&lt;/code&gt; package: &lt;a href="https://pkg.go.dev/sync" rel="noopener noreferrer"&gt;https://pkg.go.dev/sync&lt;/a&gt; from the standard library, we can control the synchrony between the different goroutines.&lt;br&gt;
A possible use is the &lt;code&gt;RWMutex&lt;/code&gt; type which allows us to lock and unlock reads and writes to a type. So if we have a type that contains a &lt;code&gt;sync.RWMutex&lt;/code&gt; and a &lt;code&gt;map&lt;/code&gt; we can control when it can be accessed.&lt;br&gt;
Another interesting type to investigate within the same &lt;code&gt;sync&lt;/code&gt; package is &lt;code&gt;Map&lt;/code&gt;, which already offers us a series of functions that will help us work with our map, which in the end we will not be able to work with natively, as with the previous solution.&lt;br&gt;
Depending on the use case we are implementing, one or the other will be more useful to us, and there is no one better than the other, it will always depend on what we need.&lt;/p&gt;

&lt;p&gt;I hope everything that I have tried to explain in this post has been clear, and please if there is any part that has not been completely clear or there are parts that I have not covered that you would like me to do, leave me a comment right here or through my social networks that you have on my profile and I will be happy to respond.&lt;/p&gt;

</description>
      <category>go</category>
      <category>maps</category>
    </item>
    <item>
      <title>Arrays and slices in Go</title>
      <dc:creator>charly3pins</dc:creator>
      <pubDate>Mon, 13 May 2024 07:47:19 +0000</pubDate>
      <link>https://forem.com/charly3pins/arrays-and-slices-in-go-5cml</link>
      <guid>https://forem.com/charly3pins/arrays-and-slices-in-go-5cml</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;When we want to group a series of elements of the same type we can do it in Go in two ways, using arrays or slices.&lt;br&gt;
Arrays have the particularity that their size is fixed and cannot be modified.&lt;br&gt;
The slices, on the other hand, have a dynamic size, so we can modify them according to our needs.&lt;/p&gt;

&lt;p&gt;Let's see an example of using slices with a "game" and thus understand why arrays are important if we are talking about slices.&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;a&lt;/span&gt; &lt;span class="o"&gt;:=&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="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="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;a&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="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&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="m"&gt;10&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;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// print original slice&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;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;/// WTF???&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Arrays
&lt;/h2&gt;

&lt;p&gt;Arrays are nothing more than a type of data to store information of the same type, sequentially, accessing it in an indexed manner.&lt;br&gt;
Arrays are values, so if we assign one array to another, all the elements from one to the other will be copied. The same thing happens in functions, you will not receive a pointer to the array, but a copy of it. The size of the array is part of its type, so [2]int is different from [10]int.&lt;br&gt;
The memory representation of an array can be seen in the following image, where it is stored in as many positions as the type indicates and in adjacent positions for that type.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F89ig9gk12yly0biyp30o.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F89ig9gk12yly0biyp30o.jpeg" alt=" " width="736" height="634"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Using arrays
&lt;/h3&gt;

&lt;p&gt;There are several ways to declare an array, let's see how we can do it.&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;languages&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thus we will have an array with zero value, and as we observe we will have 5 positions with empty text, since it is the zero value of the string type that we have chosen.&lt;/p&gt;

&lt;p&gt;To initialize the elements of the array we can do so by accessing each position by its index and indicating what value we give it:&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;languages&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="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"English"&lt;/span&gt;
&lt;span class="n"&gt;languages&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="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Spanish"&lt;/span&gt;
&lt;span class="n"&gt;languages&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="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Japanese"&lt;/span&gt;
&lt;span class="n"&gt;languages&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="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"German"&lt;/span&gt;
&lt;span class="n"&gt;languages&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="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"French"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also use the short statement and do it all in the same step:&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;languages&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;5&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;"English"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Spanish"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Japanese"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"German"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"French"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same applies to arrays of other types, for example with integers.&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;nums&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&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;nums&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// [0 0 0 0 0 0 0 0 0 0]&lt;/span&gt;
&lt;span class="c"&gt;// init values&lt;/span&gt;
&lt;span class="n"&gt;nums&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="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt;
&lt;span class="n"&gt;nums&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="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;444&lt;/span&gt;
&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;38&lt;/span&gt;
&lt;span class="n"&gt;nums&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="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;60&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;nums&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// [7 4444 0 0 0 0 38 60]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To access the elements, we use the braces &lt;code&gt;[&lt;/code&gt; and &lt;code&gt;]&lt;/code&gt; indicating the index of the position to which we want to assign the value.&lt;/p&gt;

&lt;p&gt;There are two functions that come in Go that help us work with arrays.&lt;br&gt;
&lt;code&gt;len()&lt;/code&gt; to know its length and &lt;code&gt;cap()&lt;/code&gt; to know its capacity.&lt;/p&gt;

&lt;p&gt;If we use them with the previous example we will see that in both cases it returns 10.&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="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numeros&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c"&gt;// 10&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="nb"&gt;cap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numeros&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c"&gt;// 10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the case of arrays, the capacity is not used because it is equal to the length, so len() is enough for us. Its most recurrent use is in loops to indicate that it must increase the index to the maximum -1 (the first index is 0) and access the different elements. We will see it later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multidimensional arrays
&lt;/h3&gt;

&lt;p&gt;Arrays can have more than one dimension. To do this, you must add the braces &lt;code&gt;[&lt;/code&gt; and &lt;code&gt;]&lt;/code&gt; and the number of elements of that dimension again.&lt;/p&gt;

&lt;p&gt;We can declare a multidimensional array to store animals and their sounds in the following way:&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;animalSounds&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;5&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="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;"lion"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"roar"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"dog"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"barks"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"cat"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"meows"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"frog"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"croaks"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"elephant"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"trumpets"&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;De esta forma le hemos indicado al compilador que nuestro array va a tener 5 elementos, con 2 elementos cada uno, es decir una matriz de 10 elementos, de tipo string.&lt;/p&gt;

&lt;h3&gt;
  
  
  Looping through arrays
&lt;/h3&gt;

&lt;p&gt;We have seen that to access the arrays we can use the keys &lt;code&gt;[]&lt;/code&gt; so if we make a loop that increases the value of the index it will return its 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;languages&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;5&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;"English"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Spanish"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Japanese"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"German"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"French"&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="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="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;languages&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="n"&gt;languages&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is very good, but Go offers us a specific function that simplifies this for us, the range. With range, known in other languages as foreach, the array is automatically traversed without having to worry about incrementing the index in the following way.&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;languages&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;5&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;"English"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Spanish"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Japanese"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"German"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"French"&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;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&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;languages&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;index&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;value&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;As we see, it is much simpler than not working with indexes if we do not have any extra requirements regarding access to it.&lt;/p&gt;

&lt;p&gt;If we are only interested in the value, and not the index, we can omit it using the &lt;code&gt;_&lt;/code&gt; operator.&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;languages&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;5&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;"English"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Spanish"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Japanese"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"German"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"French"&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;value&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;languages&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;value&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 the other hand, if we are only interested in the index, we can set the range equal to a single variable, and this will be the index.&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;languages&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;5&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;"English"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Spanish"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Japanese"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"German"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"French"&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;index&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;languages&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;index&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;h3&gt;
  
  
  Search in arrays
&lt;/h3&gt;

&lt;p&gt;If what we want is to know if there is an element in an array, that is, to do a search to find it, we can use the loops as we have seen previously and check each value if it is the one we were looking for, to return it or do whatever we need .&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;languages&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;5&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;"English"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Spanish"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Japanese"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"German"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"French"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"Japanese"&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;value&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;languages&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;value&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// DO LOGIC&lt;/span&gt;
        &lt;span class="k"&gt;break&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;In this example we have introduced the word &lt;code&gt;break&lt;/code&gt; which breaks the loop and exits it. It seems reasonable in the example that if we find the language we are looking for, we leave the array, but perhaps it is not what you want, so it is not mandatory to use it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add or remove elements in arrays
&lt;/h3&gt;

&lt;p&gt;As we have seen before, an array has a fixed type which indicates a length that cannot be changed. If we want to add or remove elements we can only do so by creating another array with the desired length, whether greater or less than the original.&lt;/p&gt;

&lt;p&gt;This makes it a data type that is inflexible and sometimes annoying to work with. Luckily the Go geniuses thought of everything and created another type that solves many of these problems, the Slice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Slices
&lt;/h2&gt;

&lt;p&gt;Slices can be defined as arrays of dynamic length. In reality, what happens is that slices are an abstraction created on top of arrays, offering us greater control and flexibility to work with them.&lt;/p&gt;

&lt;p&gt;What happens below is that every time we define a slice, an array is created below that we do not see, and the slice points to it using a pointer.&lt;br&gt;
For this reason, the zero value of the slice will not be N elements with zero value, with N being the length, as was the case with arrays, but will be nil, since there will be no array below to point to, so we will not have initialized pointer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fodvrfdngvq6jbn11r1jq.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fodvrfdngvq6jbn11r1jq.jpeg" alt=" " width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Using slices
&lt;/h3&gt;

&lt;p&gt;To declare a slice it is done in the same way as we have seen previously with arrays, with the only difference that we do not specify the length.&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;animals&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;"dog"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"cat"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"bird"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"horse"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As I said before, if we do not pass values, the zero value will not be empty strings, since since it does not have a length, how many should it have? So the zero value will be nil.&lt;/p&gt;

&lt;p&gt;To create slices there is also the &lt;code&gt;make&lt;/code&gt; function which has the following signature:&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="nb"&gt;make&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="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;cap&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;T is the type of elements we want in the slice, len is the length, and cap is the capacity, which is optional. If a capacity is not passed, by default the length is taken as the value.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F7k9dzjsodlgb5h3uk45v.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F7k9dzjsodlgb5h3uk45v.jpeg" alt=" " width="800" height="620"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another way to create a slice is to "cut" it. To do this, an open midrange is used with two indices separated by two points.&lt;br&gt;
In the animals example above, if we were to do &lt;code&gt;animals[1:3]&lt;/code&gt;, it would create a slice including elements 1 through 3 of animals, so "horse" would not be included in the new slice.&lt;/p&gt;

&lt;p&gt;The start and end in the indexes of a slice are optional so we can call it in these 3 ways:&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;animals&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="c"&gt;// [dog cat]&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;animals&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c"&gt;// [horse]&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;animals&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="c"&gt;// [dog cat bird horse]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create a slice from an array we can use the last form &lt;code&gt;[:]&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;languages&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;5&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;"English"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Spanish"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Japanese"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"German"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"French"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;sLanaguages&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;languages&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What must be taken into account using this method is that a copy of the array is not made below the slice, access to it is simply limited according to the range of the new slice.&lt;br&gt;
This means that if we have a slice with 1000 elements, and we make a new one with a range of 10 elements [:10], what will happen is that in the new slice we will only have 10 elements, but the array below will still have the 1000.&lt;br&gt;
Occasionally, this can cause the program to keep all of the data in memory when only a small portion is needed.&lt;/p&gt;
&lt;h3&gt;
  
  
  Add elements to a slice
&lt;/h3&gt;

&lt;p&gt;As we saw before, an array cannot modify its length since it is part of its type, but the same does not happen with slices. To do this we have to create a new slice that is longer and copy the elements of the original slice to the new one.&lt;br&gt;
To do this, Go provides us with a function called &lt;code&gt;copy(dst, src []T) int&lt;/code&gt; which makes this task easier for us:&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;languages&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;"English"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Spanish"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Japanese"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"German"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"French"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;newLanguages&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&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="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;languages&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nb"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newLanguages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;languages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sometimes what we will need is to add elements to the slice in a more or less dynamic way depending on the case, beyond creating an entire copy of the slice while maintaining both slices at the same time.&lt;br&gt;
Go helps us again with its function &lt;code&gt;append(s []T, x ...T) []T&lt;/code&gt;, which adds the element x to the end of the slice, which will grow the capacity of the slice if necessary. Every time this happens, the array below the slice doubles its length, so it is something to keep in mind if we have to do optimization work.&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;languages&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;"English"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Spanish"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Japanese"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"German"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"French"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;languages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;languages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Chinese"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In addition to this, we can also add one slice to another with &lt;code&gt;...&lt;/code&gt; as follows:&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;myNums&lt;/span&gt; &lt;span class="o"&gt;:=&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="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="n"&gt;yourNums&lt;/span&gt; &lt;span class="o"&gt;:=&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="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;6&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;myNums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myNums&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;yourNums&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// equivalent to append(myNums, yourNums[0], yourNums[1], yourNums[2])&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;myNums&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// [1 2 3 4 5 6]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Multidimensional slices
&lt;/h3&gt;

&lt;p&gt;Just like with arrays, we can declare multidimensional slices by adding more dimensions by simply adding &lt;code&gt;[]&lt;/code&gt; as &lt;code&gt;[][]int&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;animalSounds&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="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"lion"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"roar"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"dog"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"barks"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"cat"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"meows"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"frog"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"croaks"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"elephant"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"trumpets"&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;h3&gt;
  
  
  Loop through slices
&lt;/h3&gt;

&lt;p&gt;As with arrays, we can loop through the slices using the different types of loops.&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;languages&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;"English"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Spanish"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Japanese"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"German"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"French"&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="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="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;languages&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="n"&gt;languages&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also use range to cycle through the slices.&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;languages&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;"English"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Spanish"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Japanese"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"German"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"French"&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;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&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;languages&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;index&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;value&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;If we are only interested in the value, and not the index, we can omit it using the &lt;code&gt;_&lt;/code&gt; operator.&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;languages&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;"English"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Spanish"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Japanese"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"German"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"French"&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;value&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;languages&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;value&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 the other hand, if we are only interested in the index, we can set the range equal to a single variable, and this will be the index.&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;languages&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;"English"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Spanish"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Japanese"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"German"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"French"&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;index&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;languages&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;index&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;h3&gt;
  
  
  Remove elements from a slice
&lt;/h3&gt;

&lt;p&gt;Unlike arrays, with slices it is possible to eliminate elements from them, using the slicing method that we saw previously.&lt;br&gt;
We must take the slice we want and cut it in part up to the index of the element to be eliminated, and add the same slice but with the remaining part +1, to eliminate the element from the index position.&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;languages&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;"English"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Spanish"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Japanese"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"German"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"French"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;indexToRemove&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
&lt;span class="n"&gt;languages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;languages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;indexToRemove&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;languages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;indexToRemove&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;:&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sort a slice
&lt;/h3&gt;

&lt;p&gt;You can sort the elements of a slice with the Go package &lt;code&gt;sort&lt;/code&gt; &lt;a href="https://pkg.go.dev/sort" rel="noopener noreferrer"&gt;https://pkg.go.dev/sort&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="n"&gt;slice&lt;/span&gt; &lt;span class="o"&gt;:=&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="m"&gt;12&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;90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;88&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;28&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="n"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Ints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slice&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;slice&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// [2 4 5 6 12 28 88 90]&lt;/span&gt;

&lt;span class="n"&gt;languages&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;"English"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Spanish"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Japanese"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"German"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"French"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Strings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;languages&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;languages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// [English French German Japanese Spanish]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I recommend checking out the &lt;code&gt;sort&lt;/code&gt; package to understand all the options there are.&lt;/p&gt;

&lt;h3&gt;
  
  
  Search and filter items
&lt;/h3&gt;

&lt;p&gt;As with arrays, to find elements of a slice we must recreate them and check the values of each position and detect if it is what we are looking for.&lt;br&gt;
Additionally, with the slices we can filter these elements, creating a new slice without or with the elements found, depending on what we want.&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;ages&lt;/span&gt; &lt;span class="o"&gt;:=&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="m"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;23&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;38&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;45&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;adults&lt;/span&gt; &lt;span class="o"&gt;:=&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;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;age&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;ages&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;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;18&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;adults&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;adults&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&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;I hope everything that I have tried to explain in this post has been clear, and please if there is any part that has not been completely clear or there are parts that I have not covered that you would like me to do, leave me a comment right here or through my social networks that you have on my profile and I will be happy to respond.&lt;/p&gt;

</description>
      <category>go</category>
      <category>arrays</category>
      <category>slices</category>
    </item>
    <item>
      <title>Tips and tricks to code in Go in a clean, functional and effective way</title>
      <dc:creator>charly3pins</dc:creator>
      <pubDate>Wed, 08 May 2024 19:30:56 +0000</pubDate>
      <link>https://forem.com/charly3pins/tips-and-tricks-to-code-in-go-in-a-clean-functional-and-effective-way-1d60</link>
      <guid>https://forem.com/charly3pins/tips-and-tricks-to-code-in-go-in-a-clean-functional-and-effective-way-1d60</guid>
      <description>&lt;h2&gt;
  
  
  Variable names
&lt;/h2&gt;

&lt;p&gt;Go manages the visibility with lowercase for &lt;code&gt;unexported&lt;/code&gt; and uppercase for &lt;code&gt;exported&lt;/code&gt;. These concepts are valid in the context of a package, so if you declare a variable in a &lt;code&gt;package X&lt;/code&gt; with the following 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;package&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="c"&gt;// unexported&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;Bar&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="c"&gt;// exported&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will be able to call the variable &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;Bar&lt;/code&gt; while you're inside that package, but if you are in another package, you will have access only to the Bar variable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Package names
&lt;/h2&gt;

&lt;p&gt;Regarding the package names is not recommended to use the underscore &lt;code&gt;_&lt;/code&gt; in the naming, and usually a single word, although it's just a recommendation, so follow them if it makes sense for you.&lt;br&gt;
Also, the package names are used to reference the variables, constants, and types of a package, so having:&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;player&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Player&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and calling it from our main package will look like this:&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;"player"&lt;/span&gt;

&lt;span class="n"&gt;myPlayer&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Player&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we see that there is too much player verbosity, so maybe it's better to rethink the name of the package or the name of the struct.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't use Getters
&lt;/h2&gt;

&lt;p&gt;If we have a type like:&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;Player&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;Name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Dorsal&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;don't create getters for each field:&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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="n"&gt;Player&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;GetName&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;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&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;p&lt;/span&gt; &lt;span class="n"&gt;Player&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;GetDorsal&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;return&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dorsal&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Access directly to each field like &lt;code&gt;Player.Name&lt;/code&gt; or &lt;code&gt;Player.Dorsal&lt;/code&gt; or if you need a function do it without the &lt;code&gt;Get&lt;/code&gt; prefix.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interfaces
&lt;/h2&gt;

&lt;p&gt;The convention for the interfaces says that they should be a single method and named with the method name + &lt;code&gt;-er&lt;/code&gt; suffix or similar.&lt;/p&gt;

&lt;p&gt;For example, if we want to create an interface for our defenders or strikers in our Team, following the convention we would do it like this:&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;Defender&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;Defend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Striker&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;Strike&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Interface composition
&lt;/h2&gt;

&lt;p&gt;When you have a single-methods interface like the ones above, you can create another interface, composing it by those interfaces. So our Player interface will be:&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;Player&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;Defender&lt;/span&gt;
    &lt;span class="n"&gt;Striker&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  CamelCase vs snake_case
&lt;/h2&gt;

&lt;p&gt;In Go Camel Case it's the one most used. It's strange to find a snake case in any variable or constant name. In packages I already mentioned that is not recommended but sometimes you need to do it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Constants
&lt;/h2&gt;

&lt;p&gt;Constants are like variables, but with a constant value. They should not be declared all in upper case like you do in other languages. The unique upper case you should add is the first letter if you want to export it (like variables) or not.&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;const&lt;/span&gt; &lt;span class="n"&gt;Minutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;90&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;minutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;90&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;MINUTES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;90&lt;/span&gt; &lt;span class="c"&gt;// not recommended&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Grouping variables and constants
&lt;/h2&gt;

&lt;p&gt;If you are declaring more than one variable or more than one constant, you can do it as we did here, or you can group them to improve the readability of your 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;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;parts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
    &lt;span class="n"&gt;players&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;22&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;fizz&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"fizz"&lt;/span&gt;
    &lt;span class="n"&gt;buzz&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"buzz"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is super useful when you're writing a new function and at the beginning you declare the variables grouped like:&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;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&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="n"&gt;y&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;
        &lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;// Logic here&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Enums
&lt;/h2&gt;

&lt;p&gt;In Go the concept of &lt;code&gt;enums&lt;/code&gt; doesn't exist but they can be replicated using constants and a type &lt;code&gt;iota&lt;/code&gt; which is an integer enumerator. To do it, you can define your enum as:&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;Position&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Goalkeeper&lt;/span&gt; &lt;span class="n"&gt;Position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;iota&lt;/span&gt;
    &lt;span class="n"&gt;Defender&lt;/span&gt;
    &lt;span class="n"&gt;Mid&lt;/span&gt;
    &lt;span class="n"&gt;Striker&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that, you can work with the constants as usual, and they will be of type Position, instead of iota (int).&lt;br&gt;
Declaring it like this is enough most of the time but it introduces a possible bug in your code. The zero-value of the iota is 0, the same as the int, and we know that Go has zero-values by default.&lt;br&gt;
So if you define a new position but you don't initialize it with any of the constants, Since the default position is Goalkeeper, your new default position will be Goalkeeper, and perhaps it is not the behaviour you want the application to have.&lt;/p&gt;

&lt;p&gt;You can solve that in 2 ways. The first one is by simply adding +1 to the initial value, so the 0 value will not be any of the ones you defined.&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;Position&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Goalkeeper&lt;/span&gt; &lt;span class="n"&gt;Position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;iota&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;Defender&lt;/span&gt;
    &lt;span class="n"&gt;Mid&lt;/span&gt;
    &lt;span class="n"&gt;Striker&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's OK, but it still has the problem of, which Position is the value 0. To solve this, the common solution is to define the zero value as an Unknown or Default or similar value like:&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;Position&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Unknown&lt;/span&gt; &lt;span class="n"&gt;Position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;iota&lt;/span&gt;
    &lt;span class="n"&gt;Goalkeeper&lt;/span&gt;
    &lt;span class="n"&gt;Defender&lt;/span&gt;
    &lt;span class="n"&gt;Mid&lt;/span&gt;
    &lt;span class="n"&gt;Striker&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these 2 tricks, you are now ready to work with your Position enum. What if you want to print those? They are int, so you will see just numbers... maybe that's not something you care about, but if you do, here is a trick that you can do to work with strings.&lt;br&gt;
Go has the Stringer() interface with its method &lt;code&gt;String() string&lt;/code&gt; that you can satisfy with any type you want. Taking advantage of that we can do this:&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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="n"&gt;Position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&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="k"&gt;switch&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;case&lt;/span&gt; &lt;span class="n"&gt;Goalkeeper&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Goalkeeper"&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;Defender&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Defender"&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;Mid&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Mid"&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;Striker&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Striker"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Unknown"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Constructors
&lt;/h2&gt;

&lt;p&gt;Sometimes the zero value of a type isn't enough and you want to initialize your type. For that, you need to use constructors.&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;player&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Player&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;Name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Dorsal&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;func&lt;/span&gt; &lt;span class="n"&gt;NewPlayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&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;dorsal&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Player&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Player&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Dorsal&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dorsal&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;With the &lt;code&gt;NewPlayer&lt;/code&gt; function we initialize the Player values with the information provided as an argument instead of the zero values that would be "" and 0.&lt;br&gt;
Following the naming recommendation that we described before, we can refactor this into something more idiomatic, because now to call that constructor from main would look like this:&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;"player"&lt;/span&gt;

&lt;span class="n"&gt;myPlayer&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewPlayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"gopher"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;666&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better if we do a small refactor like:&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;player&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Player&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;Name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Dorsal&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;func&lt;/span&gt; &lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&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;dorsal&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Player&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Player&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Dorsal&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dorsal&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;so in our main the readability will be improved as:&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;"player"&lt;/span&gt;

&lt;span class="n"&gt;myPlayer&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"gopher"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;666&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Multiple return values
&lt;/h2&gt;

&lt;p&gt;In Go, any function or method can return multiple values, from 0 to N. The &lt;code&gt;error&lt;/code&gt; usually is returned as the latest value.&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;// 2 values return&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;Player&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Shoot&lt;/span&gt;&lt;span class="p"&gt;()&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="kt"&gt;error&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="m"&gt;99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;// single value return&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;Player&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Refill&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// do logic&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;// no return value&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;p&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Player&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Substitute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&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;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Don't use panic
&lt;/h2&gt;

&lt;p&gt;Most of the time simply returning errors is enough, but what if the error is unrecoverable and the program cannot continue? For that case exists the &lt;code&gt;panic&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The recommendation is to not use panics, but if you need to, the convention says to call the function with the prefix &lt;code&gt;Must&lt;/code&gt;. Let's see 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="c"&gt;// without panic&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;ParseFiles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// do logic&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="c"&gt;// handle error&lt;/span&gt;
        &lt;span class="k"&gt;return&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="c"&gt;//with panic&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;MustParseFiles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// do logic&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="c"&gt;// handle error&lt;/span&gt;
        &lt;span class="nb"&gt;panic&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;
  
  
  Order declaring functions for a specific type
&lt;/h2&gt;

&lt;p&gt;When you have a new type, as we saw before, most of the time you're going to create a function that acts as a constructor, and probably a list of methods for that type, maybe exported, maybe unexported.&lt;/p&gt;

&lt;p&gt;What's the best order to declare each function? Let's see what the convention says.&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;// first, declare the type&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Shape&lt;/span&gt; &lt;span class="n"&gt;strut&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="n"&gt;y&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// next, the constructor&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;NewShape&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="n"&gt;c&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Shape&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Shape&lt;/span&gt;&lt;span class="p"&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;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;c&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="c"&gt;// next, the exported methods&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;s&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Paint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&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;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// last, the unexported methods&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;s&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;()&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;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&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;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&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;color&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope everything that I have tried to explain in this post has been clear, and please if there is any part that has not been completely clear or there are parts that I have not covered that you would like me to do, leave me a comment right here or through my social networks that you have on my profile and I will be happy to respond.&lt;/p&gt;

</description>
      <category>go</category>
    </item>
    <item>
      <title>Why Go?</title>
      <dc:creator>charly3pins</dc:creator>
      <pubDate>Wed, 06 Dec 2023 11:54:34 +0000</pubDate>
      <link>https://forem.com/charly3pins/why-go-23f4</link>
      <guid>https://forem.com/charly3pins/why-go-23f4</guid>
      <description>&lt;h2&gt;
  
  
  First contact
&lt;/h2&gt;

&lt;p&gt;It's been about 8 years since I started playing with Go. At that moment I met a colleague who had left my workplace to try his luck at a new challenge in his professional career. One day talking to him he told me that they had decided to use a programming language called Go and that he was delighted with how easy it was to do things that with Java, the language we were used to using, was tremendously crude and sometimes complex, due to to the number of layers and repetitions you have to add. That's when I told him to show me how it worked and where I met Go.&lt;/p&gt;

&lt;p&gt;I tried making some API with an HTTP server and in a matter of minutes, I had it running and launching curls without any problem. That same year, a few months later, I had the opportunity to participate in an operational automation project where he worked and we did it by setting up several APIs in Go. Communicating between them, also with some AWS tools like AWS Lambda coded in Go as well. The project was a success and the biggest company decided to buy that. &lt;/p&gt;

&lt;p&gt;After that I continued working with Go in my next (current) company where I worked, building a truly microservices environment with Go as the main language in Backend replacing a Typescript monolith.&lt;/p&gt;

&lt;p&gt;Why we have chosen &lt;code&gt;Go&lt;/code&gt;? Let me try to number a few things that made us choose Go versus other programming languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Manifest
&lt;/h2&gt;

&lt;p&gt;Go &lt;code&gt;code is very obvious&lt;/code&gt;, there is the joke that it is a boring code, and that's fantastic.&lt;/p&gt;

&lt;p&gt;Go is a really &lt;code&gt;fast language&lt;/code&gt;. Because Go is compiled, it will naturally outperform languages that are interpreted or have virtual runtimes. The compiling time is extremely fast, and the resulting binary is very small. That allows you to deploy several times every day, so that follows the DevOps methodology perfectly.&lt;/p&gt;

&lt;p&gt;Go's &lt;code&gt;syntax is small but powerful&lt;/code&gt;, so it's easy to learn. You can fit most of it in your head, which means you don't need to spend a lot of time looking things up. It's also very clean and easy to read. Non-Go programmers, especially those used to a C-style syntax, can read a Go program and usually understand what's going on.&lt;/p&gt;

&lt;p&gt;Go is a &lt;code&gt;strongly, statically typed language&lt;/code&gt;. There are primitive types like int, byte, and string. There are also structs. Like any strongly typed language, the type system allows the compiler to help catch entire classes of bugs. Go also has built-in types for lists and maps, and they are easy to use.&lt;/p&gt;

&lt;p&gt;Go has &lt;code&gt;interfaces&lt;/code&gt;, and any struct can satisfy an interface simply by implementing its methods. Go also has first-class functions, which open up the possibility to write your code in a more functional style.&lt;/p&gt;

&lt;p&gt;Go has a nice &lt;code&gt;standard library&lt;/code&gt;, so usually the Go programs have few external dependencies. It provides handy built-in functions for working with primitive types. Some packages make it easy to set up a web server, handle I/O, and data manipulation. JSON serialization and deserialization provided by the standard library is trivial.&lt;/p&gt;

&lt;p&gt;Go makes &lt;code&gt;concurrency&lt;/code&gt; easier than in other languages. Using goroutine(s) and channel(s) it's almost trivial, while more complex patterns are possible.&lt;/p&gt;

&lt;p&gt;Go provides out-of-the-box &lt;code&gt;testing&lt;/code&gt; support in its standard library. There is no need for an extra dependency. If you have a file called thing.go, write your tests in another file called thing_test.go, and run "go test". Go will execute those tests automatically.&lt;/p&gt;

&lt;p&gt;Go &lt;code&gt;static analysis tools&lt;/code&gt; are numerous and robust. One in particular is &lt;code&gt;gofmt&lt;/code&gt;, which formats your code according to Go's suggested style. Since there is a single code format and a great standard lib, you can focus on creating business value, not discussing where to put this condition or how to define that data structure.&lt;/p&gt;

&lt;p&gt;Go provides a &lt;code&gt;memory safe&lt;/code&gt; allocating dynamic objects and &lt;code&gt;garbage collecting&lt;/code&gt; them, all that is made simpler than C and C++. Also, it makes using pointers much safer because it doesn't allow pointer arithmetic. It also gives you the option of using value types.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bonus&lt;/strong&gt;&lt;br&gt;
Go coding style follows the &lt;a href="https://medium.com/@matryer/line-of-sight-in-code-186dd7cdea88" rel="noopener noreferrer"&gt;line of sight&lt;/a&gt;: the idea is that down the edge of your function, should be the happy path, so it's in the left edge. Anything else, being an error or an edge case, it's not the happy path, so you should indent it. With that, the code is super readable and easy to follow, and you don't need to use &lt;code&gt;else&lt;/code&gt; in probably 99% of the cases. When you have in front of you the Go code and you see there is a part of the code indented, you know that's the exit of the function and the happy path it's on the left edge.&lt;/p&gt;

&lt;p&gt;Simple, clean, great, GO!&lt;/p&gt;

&lt;p&gt;I hope everything that I have tried to explain in this post has been clear, and please if there is any part that has not been completely clear or there are parts that I have not covered that you would like me to do, leave me a comment right here or through my social networks that you have on my profile and I will be happy to respond.&lt;/p&gt;

</description>
      <category>go</category>
    </item>
    <item>
      <title>I generated my CV using Go templates</title>
      <dc:creator>charly3pins</dc:creator>
      <pubDate>Sat, 23 Sep 2023 09:48:22 +0000</pubDate>
      <link>https://forem.com/charly3pins/i-generated-my-cv-using-go-templates-4d44</link>
      <guid>https://forem.com/charly3pins/i-generated-my-cv-using-go-templates-4d44</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you need to present any kind of data in a structured and formatted way you could find this article interesting. Go provides a way to do this in an easy and effective manner with two packages, &lt;code&gt;text/template&lt;/code&gt; and &lt;code&gt;html/template&lt;/code&gt;. The first one is focused on formatting texts in general and I am using it to generate my README page in GitHub. You can find the details in &lt;a href="https://github.com/charly3pins/charly3pins" rel="noopener noreferrer"&gt;https://github.com/charly3pins/charly3pins&lt;/a&gt;. In this article, I am going to cover the second one, the templating for HTML pages. It's true that at the end I will generate a PDF from it but let's go step by step!&lt;br&gt;
I recommend you read the &lt;a href="https://pkg.go.dev/html/template" rel="noopener noreferrer"&gt;documentation page&lt;/a&gt; since I'm not going to cover the whys and whats about the package, only showing you how I organized the templates and how I generate my Resume using it.&lt;/p&gt;
&lt;h2&gt;
  
  
  CV Template
&lt;/h2&gt;

&lt;p&gt;First of all I created a YAML file where I will store all my CV information called &lt;code&gt;me.yaml&lt;/code&gt;. The structure that I decided on was the following one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;Role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;Email&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;Web&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;Location&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;Mission&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;Skills&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;Experience&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;Entity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;Started&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;Stopped&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;Location&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;Details&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;Projects&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;Education&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;Languages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;Keywords&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(I removed all the data to make it readable but you can get an idea of what is inside each key).&lt;/p&gt;

&lt;p&gt;After that, I started creating the base template for the HTML page that I wanted to generate. I stored it inside &lt;code&gt;tmpl/base.html&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;{{ define "base" }}
&lt;span class="cp"&gt;&amp;lt;!doctype html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;'en-US'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;{{.Name}} | {{.Role}}&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
{{ end }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the base only, so there is no data displayed yet, only the Name and the Role. &lt;/p&gt;

&lt;p&gt;For maintainability reasons, I split each section of my CV into a partial template. All partial templates I stored inside &lt;code&gt;tmpl/partials/&lt;/code&gt;. So for example, I created the &lt;code&gt;about.html&lt;/code&gt; that is as simple as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;about&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;'grid-area: name'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{.Name}}&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;'grid-area: role'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{.Role}}&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;contact&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;'grid-area: contact'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"mailto:{{.Email}}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{.Email}}&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt; • &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{.Web}}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{.Web}}&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And other(s) with more logic like the &lt;code&gt;experience.html&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;experience&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Experience&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
{{ range .Experience }}
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;employer&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&amp;lt;strong&amp;gt;&lt;/span&gt;{{.Role}}&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;dates&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{.Started}} - {{if .Stopped}}{{.Stopped}}{{else}}Present{{end}}&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;entity&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{.Entity}} &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;loc&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;({{.Location}})&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;deets&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
{{ range .Details }}
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;deet&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{- . -}}&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
{{end}}
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
{{end}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After creating all the needed ones, I added them inside the base one created before using the &lt;code&gt;{{template}}&lt;/code&gt; action to invoke the partials in the place that I desired. The resulting &lt;code&gt;base.html&lt;/code&gt; looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;{{ define "base" }}
&lt;span class="cp"&gt;&amp;lt;!doctype html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;'en-US'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;{{.Name}} | {{.Role}}&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
    {{ template "about.html" . }}
    {{ template "mission.html" . }}
    &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
    {{ template "skills.html" . }}
    &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
    {{ template "experience.html" . }}
    &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
    {{ template "projects.html" . }}
    &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
    {{ template "education.html" . }}
    &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
    {{ template "keywords.html" . }}
    &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
    {{ template "languages.html" . }}
  &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
{{ end }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have chosen this order but you can order the partials however you want and repeat them as many times as you want, there is no limitation in that regard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating the HTML page
&lt;/h2&gt;

&lt;p&gt;Cool! At this point, we have our "Database" in our YAML file, and we have our base template invoking our partial templates, so the only point we are missing is to combine the data with the templates and generate our HTML page to have our CV published.&lt;/p&gt;

&lt;p&gt;I created a &lt;code&gt;main.go&lt;/code&gt; in the root of the project and I added the following 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;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;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"os"&lt;/span&gt;
    &lt;span class="s"&gt;"html/template"&lt;/span&gt;

    &lt;span class="s"&gt;"gopkg.in/yaml.v3"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;datafileName&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"me.yaml"&lt;/span&gt;
    &lt;span class="n"&gt;resumeFileName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"resume.html"&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;files&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;"./tmpl/base.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"./tmpl/partials/about.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"./tmpl/partials/education.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"./tmpl/partials/experience.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"./tmpl/partials/keywords.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"./tmpl/partials/languages.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"./tmpl/partials/mission.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"./tmpl/partials/projects.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"./tmpl/partials/skills.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;templates&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;template&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ParseFiles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="o"&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;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;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Print&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;Error&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&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="n"&gt;buf&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;os&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="n"&gt;datafileName&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;log&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;"err reading data file"&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="k"&gt;return&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;yaml&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="n"&gt;buf&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;data&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;log&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;"err unmarshaling data"&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="k"&gt;return&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;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resumeFileName&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;log&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;"error creating file"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resumeFileName&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="k"&gt;return&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;templates&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExecuteTemplate&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="s"&gt;"base"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&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;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Print&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;Error&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;I used the &lt;code&gt;gopkg.in/yaml.v3&lt;/code&gt; library to work with YAML easily but you can find probably others that serve your purpose but I'm used to working with this one.&lt;/p&gt;

&lt;p&gt;Then I declared the constants for the YAML and HTML filenames.&lt;/p&gt;

&lt;p&gt;After that inside the &lt;code&gt;main()&lt;/code&gt; I have that slice of strings where I indicate all my templates and its path. I think this can be simplified in the future using another function from the package but for now, I wanted to have it as simple as possible.&lt;/p&gt;

&lt;p&gt;The next step is to parse the files I want to use as templates. The package provides the function &lt;code&gt;func (t *Template) ParseFiles(filenames ...string) (*Template, error)&lt;/code&gt;, so I just passed my slice to it and then all the templates are ready to be used at any point.&lt;/p&gt;

&lt;p&gt;The other piece that I needed was to parse the YAML file and for that, I simply read the file where I have all the information and then used the lib mentioned before unmarshaling it to a &lt;code&gt;map[string]interface{}{}&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Having the templates parsed and the information loaded, the third file that comes to the table game is the final HTML. I just used the function &lt;code&gt;func Create(name string) (*File, error)&lt;/code&gt; to create that.&lt;/p&gt;

&lt;p&gt;Lastly, I glued all the parts with the executino of the template with the following function &lt;code&gt;func (t *Template) ExecuteTemplate(wr io.Writer, name string, data any) error&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first argument is an &lt;code&gt;io.Writter&lt;/code&gt; so our HTML file.&lt;/li&gt;
&lt;li&gt;The second one is the name of the template that we want to execute. In our case we only defined one template (even though we created multiple partials, we only defined the &lt;code&gt;base&lt;/code&gt; one with the command &lt;code&gt;{{ define "base" }}&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The last one is the data we want to pass (if any) to our template, so our loaded YAML file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To generate the &lt;code&gt;resume.html&lt;/code&gt; file, I run from the root directory:&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="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;I hope that this easy and simple example has helped you learn or expand your knowledge in the use of templates in Go and that it has given you ideas on how to generate your pages in HTML or in text to format your texts in an organized and structured way without having to worry about anything beyond generating the template and the data structure to satisfy said template.&lt;/p&gt;

&lt;p&gt;You can find the complete source code in &lt;a href="https://github.com/charly3pins/cv" rel="noopener noreferrer"&gt;https://github.com/charly3pins/cv&lt;/a&gt; where I added some CSS and more fancy stuff to improve virtually the Resume and where I will be adding updates in the future.&lt;/p&gt;

&lt;p&gt;I hope everything that I have tried to explain in this post has been clear, and please if there is any part that has not been completely clear or there are parts that I have not covered that you would like me to do, leave me a comment right here or through my social networks that you have on my profile and I will be happy to respond.&lt;/p&gt;

</description>
      <category>go</category>
      <category>html</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Tech Book Club</title>
      <dc:creator>charly3pins</dc:creator>
      <pubDate>Sat, 15 Apr 2023 08:51:26 +0000</pubDate>
      <link>https://forem.com/charly3pins/tech-book-club-1bh1</link>
      <guid>https://forem.com/charly3pins/tech-book-club-1bh1</guid>
      <description>&lt;h2&gt;
  
  
  What is that?
&lt;/h2&gt;

&lt;p&gt;The purpose of any club is to bring a group of people together to learn and discuss something that matters to them, have fun doing it, and end up having a positive impact on them. A book club is no different.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why did we start one?
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://arex.io/" rel="noopener noreferrer"&gt;AREX&lt;/a&gt; we have a team that loves to explore and talk about different technical ideas to improve our code base, ways of working, methodologies, culture and so on. We have a strong learning culture and we constantly encourage our employees to improve themselves. So what happened before creating the club was that some people were exploring different topics individually but after that the discussion with the other members was not possible since the level of knowledge was not the same (except in some occasions that could be the case). So as engineers that we are, we started to think how we can solve that gap and we ended up deciding to create the &lt;code&gt;Tech Book Club&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The main points for us are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Have a common space where we can discuss with the same knowledge base.&lt;/li&gt;
&lt;li&gt;Sharing ideas is the key to success. 2 people can read the same thing and understand something completely different. So it is very important for us to share those ideas and discuss them to reach agreements. &lt;/li&gt;
&lt;li&gt;The previous technical knowledge you have is not important. Everyone is welcome to join the reading and discussion in a respectful and inclusive way.&lt;/li&gt;
&lt;li&gt;All club members are improving, so the level of the company improves as well.&lt;/li&gt;
&lt;li&gt;We learn in a fun way.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How does it work?
&lt;/h2&gt;

&lt;p&gt;We have a dedicated Slack channel for the club, so everything related to it is posted there. Before we start a new book, we ask the members to propose the next book(s) they consider interesting to read and a brief description of why we should read it.&lt;br&gt;
Then we put all the books in a poll and we vote during a few days and the book with more votes will be the one selected.&lt;br&gt;
We use the &lt;a href="https://www.oreilly.com/" rel="noopener noreferrer"&gt;O'Reilly Media&lt;/a&gt; platform for that. There we have a playlist in the website where we add the books that we are reading and the members have access to that list, so we can share the same links between us in order to facilitate the communication.&lt;br&gt;
Every 2 weeks we have a meeting where we have a discussion about what we have read, what we liked, what we don't like, if we can apply something to our company. At the end of the session we agree on the number of pages / sections / chapters for the next session. Sometimes it's difficult to calculate what's the right &lt;br&gt;
After each meeting we log the session into a Confluence page for keeping track of the highlights. So at the end of the book we have all the highlights summarised in one place.&lt;/p&gt;

&lt;p&gt;One idea that we have for the future (because currently we don't have time) is to send out a survey after each session. This will help us to know from the members, what worked and what didn't work and improve for the next session.&lt;/p&gt;

&lt;h2&gt;
  
  
  The books
&lt;/h2&gt;

&lt;p&gt;The Tech Book Club started in December 2021 and we've read completely 3 books:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Microservices Patterns, by Chris Richardson&lt;/li&gt;
&lt;li&gt;Rocket Surgery Made Easy: The Do-It-Yourself Guide to Finding and Fixing Usability Problems, by Steve Krug&lt;/li&gt;
&lt;li&gt;Test Driven Development: By Example, by Kent Beck&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Currently we are reading Software Engineering at Google, by Titus Winters, Tom Manshreck, Hyrum Wright.&lt;/p&gt;

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

&lt;p&gt;A Tech Book Club is a great way to level up your team in an inclusive, safe and fun way. That will have a positive impact on them, but also at the company level. Also, don't neglect inviting other departments to the club as it will help build social connections and improve collaboration between them, so don't make it private just for your team.&lt;/p&gt;

&lt;p&gt;I hope everything that I have tried to explain in this post has been clear and please if there is any part that has not been completely clear or there are parts that I have not covered that you would like me to do, leave me a comment right here or through my social networks that you have on my profile and I will be happy to respond.&lt;/p&gt;

</description>
      <category>engineering</category>
      <category>bookclub</category>
      <category>teambuilding</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Club de Lectura de Tecnología</title>
      <dc:creator>charly3pins</dc:creator>
      <pubDate>Sat, 15 Apr 2023 08:51:18 +0000</pubDate>
      <link>https://forem.com/charly3pins/club-de-lectura-de-tecnologia-172</link>
      <guid>https://forem.com/charly3pins/club-de-lectura-de-tecnologia-172</guid>
      <description>&lt;h2&gt;
  
  
  ¿Qué es eso?
&lt;/h2&gt;

&lt;p&gt;El propósito de cualquier club es reunir a un grupo de personas para aprender y discutir algo que les importe, divertirse haciéndolo y terminar teniendo un impacto positivo en ellos. Un club de lectura no es diferente.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Por qué empezamos uno?
&lt;/h2&gt;

&lt;p&gt;En &lt;a href="https://arex.io/" rel="noopener noreferrer"&gt;AREX&lt;/a&gt; contamos con un equipo al que le encanta explorar y hablar sobre diferentes ideas técnicas para mejorar nuestra base de código, formas de trabajar, metodologías, cultura, etc. Tenemos una fuerte cultura de aprendizaje y animamos constantemente a nuestros empleados a mejorar. Entonces lo que pasó antes de crear el club fue que algunas personas estaban explorando diferentes temas individualmente pero después de eso la discusión con los otros miembros no era posible ya que el nivel de conocimiento no era el mismo (excepto en algunas ocasiones que podría ser el caso). Entonces, como ingenieros que somos, comenzamos a pensar cómo podemos resolver esa brecha y terminamos decidiendo crear el &lt;code&gt;Tech Book Club&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Los puntos principales para nosotros son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tener un espacio común donde podamos discutir con la misma base de conocimiento.&lt;/li&gt;
&lt;li&gt;Compartir ideas es la clave del éxito. 2 personas pueden leer lo mismo y entender algo completamente diferente. Entonces es muy importante para nosotros compartir esas ideas y discutirlas para llegar a acuerdos.&lt;/li&gt;
&lt;li&gt;Los conocimientos técnicos previos que tengas no son importantes. Todos son bienvenidos a unirse a la lectura y la discusión de una manera respetuosa e inclusiva.&lt;/li&gt;
&lt;li&gt;Todos los miembros del club están mejorando, por lo que también mejora el nivel de la empresa.&lt;/li&gt;
&lt;li&gt;Aprendemos de una manera divertida.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ¿Como funciona?
&lt;/h2&gt;

&lt;p&gt;Tenemos un canal de Slack exclusivo para el club, por lo que todo lo relacionado con él se publica allí. Antes de comenzar un nuevo libro, les pedimos a los miembros que propongan los próximos libros que consideren interesantes para leer y una breve descripción de por qué deberíamos leerlo.&lt;br&gt;
Luego ponemos todos los libros en una encuesta y votamos durante unos días y el libro con más votos será el seleccionado.&lt;br&gt;
Usamos la plataforma &lt;a href="https://www.oreilly.com/" rel="noopener noreferrer"&gt;O'Reilly Media&lt;/a&gt; para eso. Allí tenemos una lista de reproducción en el sitio web donde agregamos los libros que estamos leyendo y los miembros tienen acceso a esa lista, por lo que podemos compartir los mismos enlaces entre nosotros para facilitar la comunicación.&lt;br&gt;
Cada 2 semanas tenemos una reunión donde tenemos una discusión sobre lo que hemos leído, lo que nos gustó, lo que no nos gusta, si podemos aplicar algo a nuestra empresa. Al final de la sesión acordamos el número de páginas/secciones/capítulos para la siguiente sesión. A veces es difícil calcular qué es lo correcto&lt;br&gt;
Después de cada reunión, registramos la sesión en una página de Confluence para realizar un seguimiento de los aspectos más destacados. Así que al final del libro tenemos todos los puntos destacados resumidos en un solo lugar.&lt;/p&gt;

&lt;p&gt;Una idea que tenemos para el futuro (porque actualmente no tenemos tiempo) es enviar una encuesta después de cada sesión. Esto nos ayudará a saber de los miembros directamente, qué funcionó y qué no funcionó y mejorar para la próxima sesión.&lt;/p&gt;

&lt;h2&gt;
  
  
  Los libros
&lt;/h2&gt;

&lt;p&gt;El Club de Lectura de Tecnología comenzó en diciembre de 2021 y hemos leído 3 libros completos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Microservices Patterns, de Chris Richardson&lt;/li&gt;
&lt;li&gt;Rocket Surgery Made Easy: The Do-It-Yourself Guide to Finding and Fixing Usability Problems, de Steve Krug&lt;/li&gt;
&lt;li&gt;Test Driven Development: By Example, de Kent Beck&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Actualmente estamos leyendo Software Engineering at Google, de Titus Winters, Tom Manshreck, Hyrum Wright.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;Un Club de Lectura de Tecnología es una excelente manera de subir de nivel a su equipo de una manera inclusiva, segura y divertida. Eso tendrá un impacto positivo en ellos, pero también a nivel de empresa. Además, no olvide invitar a otros departamentos al club, ya que ayudará a establecer conexiones sociales y mejorará la colaboración entre ellos, así que no lo haga privado solo para su equipo.&lt;/p&gt;

&lt;p&gt;Espero que todo lo que he intentado explicar en este post haya sido claro, y por favor si hay alguna parte que no ha sido del todo clara o hay partes que no he cubierto que te gustaría que hiciera, déjame un comentario aquí mismo oa través de mis redes sociales que tienes en mi perfil y estaré encantado de responderte.&lt;/p&gt;

</description>
      <category>ingenieria</category>
      <category>bookclub</category>
      <category>productividad</category>
      <category>teambuilding</category>
    </item>
    <item>
      <title>Estructura de proyecto para Go con Arquitecturas Limpias y DDD</title>
      <dc:creator>charly3pins</dc:creator>
      <pubDate>Thu, 09 Dec 2021 15:21:09 +0000</pubDate>
      <link>https://forem.com/charly3pins/estructura-de-proyecto-para-go-con-arquitecturas-limpias-y-ddd-1me4</link>
      <guid>https://forem.com/charly3pins/estructura-de-proyecto-para-go-con-arquitecturas-limpias-y-ddd-1me4</guid>
      <description>&lt;h2&gt;
  
  
  Introducción
&lt;/h2&gt;

&lt;p&gt;Durante los últimos 5 años he trabajado a tiempo completo con Go. Algunos de ustedes ya sabrán que estoy enamorado de este lenguaje por la simplicidad que tiene pero con mucho potencial para construir cualquier cosa. La principal pregunta a la que me he enfrentado desde el principio es &lt;code&gt;¿Qué estructura debo usar para mi proyecto?&lt;/code&gt; Yo diría que todavía hoy no lo sé y como siempre en nuestra industria... &lt;code&gt;depende&lt;/code&gt;. Depende de si está creando una libreria, depende de si está creando una aplicación monolítica (como MVC), depende de si está creando un pequeño servicio (también conocido como microservicio), etc. No hay nada escrito y no hay muchos frameworks (afortunadamente) que te obligan a hacer las cosas a la manera del mismo (tenga en cuenta que esa es una de mis partes favoritas, especialmente viniendo de Java, donde Spring parece ser la forma estándar de hacer proyectos en Java). Para los principiantes, a veces eso es lo difícil porque no sabes cómo empezar y necesitas investigar y leer/ver algunos tutoriales y tratar de imitar esos diseños sin saber si estás haciendo las cosas correctamente. Lo bueno de esto es que, como no existe un estándar, "todo" lo que hagas estará bien (aunque a veces es peligroso).&lt;/p&gt;

&lt;h2&gt;
  
  
  Primer enfoque
&lt;/h2&gt;

&lt;p&gt;Cuando comencé, busqué muchos repositorios en GitHub usando la etiqueta #Go y ver cómo las personas estaban organizando sus proyectos. Comprobando desde los más pequeños hasta los más grandes de la industria como Docker, Kubernetes, AWS, ... Mi primer enfoque fue usar la todavía popular doble carpeta:&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="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;pkg&lt;/span&gt;
&lt;span class="n"&gt;archivos&lt;/span&gt; &lt;span class="n"&gt;de&lt;/span&gt; &lt;span class="n"&gt;configuración&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Makefile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este fue el enfoque inicial que estaban adoptando algunos proyectos de Go, donde dentro del &lt;code&gt;pkg&lt;/code&gt; usted define todo su código y en el &lt;code&gt;cmd&lt;/code&gt; simplemente crea su &lt;code&gt;main.go&lt;/code&gt; el cuál arranca su aplicación desde el &lt;code&gt;pkg&lt;/code&gt;. Esto comenzó a ser tan popular porque se utilizaron algunos ejemplos de Go del equipo de Go. Algunos meses / años después, algunas personas comenzaron a preguntarse si la carpeta &lt;code&gt;pkg&lt;/code&gt; era simplemente eso, una carpeta, y no contribuía en nada al proyecto, por lo que debería eliminarse. En ese momento yo era un claro defensor del diseño &lt;code&gt;cmd, pkg&lt;/code&gt; porque era un "estándar" para la industria y para mí estaba claro dónde mirar el código (pkg) y dónde mirar la inicialización de la aplicación (cmd). Esto sigue siendo cierto, pero defendiendo la simplicidad de Go, tendemos a eliminar los paquetes que son solo carpetas y darles también un nombre significativo, ya que son parte de nuestro código (importándolos y usándolos en tipos, funciones, etc.).&lt;/p&gt;

&lt;h2&gt;
  
  
  Momento Ahá
&lt;/h2&gt;

&lt;p&gt;Hace unos años comencé a leer sobre DDD debido a la popularidad que ha adquirido en los últimos años y quería saber de qué se trata. No quiero extenderme en este post sobre ese tema (si desea que escriba uno específico para él, envíeme un mensaje aquí o a través de mis redes sociales y estaré feliz de hacerlo) pero básicamente a lo que apunta es a concentrarse al diseñar en el dominio en lugar de en el código. Le ayuda a comprender mejor el problema al brindarle un conjunto de herramientas para trabajar con los expertos en el dominio de su empresa a fin de diseñar la mejor solución posible para el problema que desea resolver. Hay dos grupos principales, los patrones estratégicos y los patrones tácticos. Ambos son importantes, pero aquí, como quiero hablar sobre el diseño del proyecto, solo hablaré de los tácticos. Cuando leí esos, comencé a internalizar que todo el diseño de dominio que estaba haciendo con los patrones estratégicos, todas las preguntas que le hacía a los expertos en el dominio, el lenguaje ubicuo que estábamos definiendo y todas las sesiones de tormenta de eventos que estábamos haciendo, todo eso debería reflejarse en mi código. ¿Cómo puedo hacer eso? Hay muchas posibilidades, pero una posibilidad es usar Clean Architectures.&lt;br&gt;
En ese momento fue cuando leí el libro de Robert C. Martin 'Arquitectura limpia: Una guía del artesano para la estructura y el diseño del software: Una guía del artesano para la estructura y el diseño del software'. Entendiendo los objetivos de DDD y las ideas transmitidas en el libro y después de un refinamiento con los compañeros de mi equipo, terminamos creando un diseño de proyecto en el que intentamos reunir todos esos conceptos y los más importantes con los que nos sentimos cómodos trabajando. Esto no es para seguir una tendencia o una imposición de ningún marco, por lo que si no estamos contentos con él, lo repetimos nuevamente y retocamos las partes que consideramos para facilitar nuestra vida y especialmente nuestro yo futuro cuando lo necesitemos. algunas correcciones o agregar nuevas funciones.&lt;/p&gt;
&lt;h2&gt;
  
  
  El diseño
&lt;/h2&gt;

&lt;p&gt;Teniendo en cuenta todo lo que mencioné antes, permítanme presentarles el diseño del proyecto. Como ejemplo, usaré una aplicación que tiene salientes y pagos recibidos. Ambos con sus propios agregados y reglas comerciales que deben satisfacer y exponer los endpoints a través de grpc en este caso.&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="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;payments&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;svc&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;docs&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;grpc&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;incoming&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;internal&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;
    &lt;span class="o"&gt;|-&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
    &lt;span class="o"&gt;|-&lt;/span&gt; &lt;span class="n"&gt;postgres&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
    &lt;span class="o"&gt;|-&lt;/span&gt; &lt;span class="n"&gt;slack&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;k8s&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;outgoing&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;compose&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;yml&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="k"&gt;go&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;
&lt;span class="n"&gt;Makefile&lt;/span&gt;
&lt;span class="n"&gt;README&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;md&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Intentaré ser breve y explicar un poco qué partes contiene cada carpeta y por qué adoptamos ese diseño.&lt;/p&gt;

&lt;p&gt;Como dije, este servicio es responsable de los pagos, por lo que queremos que el dominio se exponga primero, por lo que mostramos &lt;code&gt;incoming&lt;/code&gt; y &lt;code&gt;outgoing&lt;/code&gt; como las partes principales de la aplicación. Entraré en detalle unas líneas después, no se preocupe.&lt;/p&gt;

&lt;p&gt;En &lt;code&gt;app&lt;/code&gt; es donde tenemos el &lt;code&gt;main.go&lt;/code&gt; para arrancar todas las aplicaciones (básicamente donde importamos los paquetes incoming y outgoing y algunos internal si es necesario).&lt;/p&gt;

&lt;p&gt;En &lt;code&gt;cmd&lt;/code&gt; es donde definimos las herramientas de línea de comando que necesitamos para el servicio. En este caso tenemos un cli que interactúa con nuestro servicio.&lt;/p&gt;

&lt;p&gt;En &lt;code&gt;docs&lt;/code&gt; es donde colocamos la documentación relevante para este proyecto.&lt;/p&gt;

&lt;p&gt;Como mencioné antes, los endpoints se exponen a través de &lt;code&gt;grpc&lt;/code&gt;, por lo que la carpeta es responsable de implementar las interfaces proporcionadas por la compilación de nuestro &lt;a href="https://developers.google.com/protocol-buffers" rel="noopener noreferrer"&gt;protobuffer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;En &lt;code&gt;internal&lt;/code&gt; es donde tenemos la implementación de las interfaces que usamos en el proyecto pero que no son parte del dominio; básicamente las cosas de la infraestructura como la base de datos, las colas, los servicios externos (Slack), el logger...&lt;/p&gt;

&lt;p&gt;En &lt;code&gt;k8s&lt;/code&gt; se refiere a los archivos de configuración de Kubernetes para la implementación.&lt;/p&gt;

&lt;p&gt;Como se mencionó antes, &lt;code&gt;incoming&lt;/code&gt; y &lt;code&gt;outgoing&lt;/code&gt; son nuestros paquetes de dominio, así que ahí es donde ocurre toda la magia. Describiré un poco uno de ellos porque el otro es similar pero con las particularidades de su dominio.&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="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;outgoing&lt;/span&gt;
&lt;span class="n"&gt;app_service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="n"&gt;app_service_test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="n"&gt;display_payments&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="n"&gt;display_payments_test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="n"&gt;execute_payments&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="n"&gt;execute_payments_test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="n"&gt;flow_service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="n"&gt;flow_service_test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="n"&gt;instruction_repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="n"&gt;instruction_repository_test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="n"&gt;instruction&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="n"&gt;instruction_test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recogí el "saliente" para la explicación. En primer lugar tenemos el &lt;code&gt;app_service&lt;/code&gt;. Aquí es donde definimos el tipo Application Service de nuestro paquete, entonces lo que significa es que tendrá todas las dependencias para el paquete y un método para cada Caso de Uso. Nota: las dependencias son interfaces. El &lt;code&gt;app_service_test&lt;/code&gt; es básicamente donde mockeamos todas las interfaces necesarias para el app_service para poder reutilizarlas en todos los archivos &lt;code&gt;*_test.go&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Los ficheros &lt;code&gt;display_payments&lt;/code&gt; y &lt;code&gt;execute_payments&lt;/code&gt; son casos de uso para este dominio. Las test simplemente prueban los diferentes escenarios para cada caso de uso.&lt;/p&gt;

&lt;p&gt;El &lt;code&gt;flow_service&lt;/code&gt; es un servicio de dominio que nos ayuda a ejecutar los pagos en función del flujo definido para cada tipo de pago. Básicamente, el test consiste en probar el servicio de dominio.&lt;/p&gt;

&lt;p&gt;El &lt;code&gt;instruction_repository&lt;/code&gt; es donde definimos todos los métodos contra nuestro repositorio, en este caso nuestra base de datos en PostgreSQL. En el test se compara con una base de datos de prueba si todas las consultas están bien.&lt;/p&gt;

&lt;p&gt;Por último, pero no menos importante, en realidad lo más importante el agregado &lt;code&gt;instruction&lt;/code&gt;. Dentro de ese archivo es donde ponemos todo lo importante para este paquete. El agregado está a cargo de hacer cumplir las reglas de negocio por lo que todas las validaciones, verificaciones, cálculos, conversiones, etc. deben estar aquí. (Es cierto que dependiendo de la conversión o manipulaciones de datos o otras operaciones más complejas, es mejor tener factorías u otros helpers, pero no quiero complicar demasiado este ejemplo).&lt;/p&gt;

&lt;h2&gt;
  
  
  Flujo de la aplicación
&lt;/h2&gt;

&lt;p&gt;Para finalizar este largo post, permítanme describir cómo funciona el flujo de nuestra aplicación:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;app&lt;/code&gt; es la responsable de poner en marcha el servicio&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;grpc&lt;/code&gt; será el que reciba la solicitud y responda los resultados&lt;/li&gt;
&lt;li&gt;una vez que &lt;code&gt;grpc&lt;/code&gt; asigna la solicitud a nuestros tipos internos, llamará a &lt;code&gt;app_service&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;dentro de &lt;code&gt;app_service&lt;/code&gt; se llamará al &lt;code&gt;caso de uso&lt;/code&gt; correspondiente&lt;/li&gt;
&lt;li&gt;dependiendo del &lt;code&gt;caso de uso&lt;/code&gt; se debe llamar algún &lt;code&gt;servicio de dominio&lt;/code&gt;, se llamará algún &lt;code&gt;repositorio&lt;/code&gt;, o ambos, o más de 2 ... ¡Depende!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;Espero que todo lo que he intentado explicar en este post haya sido claro, que fue mucho, y por favor si hay alguna parte que no ha sido del todo clara o hay partes que no he cubierto que te gustaría que hiciera, déjame un comentario aquí mismo oa través de mis redes sociales que tienes en mi perfil y estaré encantado de responderte.&lt;/p&gt;

</description>
      <category>go</category>
      <category>architecture</category>
      <category>ddd</category>
    </item>
    <item>
      <title>Go project layout with Clean architectures and DDD</title>
      <dc:creator>charly3pins</dc:creator>
      <pubDate>Thu, 09 Dec 2021 15:19:28 +0000</pubDate>
      <link>https://forem.com/charly3pins/go-project-layout-with-clean-architectures-and-ddd-2p62</link>
      <guid>https://forem.com/charly3pins/go-project-layout-with-clean-architectures-and-ddd-2p62</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;During the last 5 years I have been working full time with Go. Some of you may already know that I'm in love with this language because of the simplicity it has but with a lot of potential to build anything. The main question I have faced since the beginning is &lt;code&gt;Which layout should I use for my project?&lt;/code&gt; I would say still today I don't know and as always in our industry... &lt;code&gt;it depends&lt;/code&gt;. It depends on if you are building a library, it depends on if you are building a monolithic application (like MVC), it depends on if you are building a small service (aka microservice), etc. There is nothing written of and we don't have a lot (luckily) frameworks that force you to do things in the framework's way (note aside that's one of my favorite parts especially coming from Java where Spring seems to be the standard way of doing projects in Java). For the beginners sometimes that is difficult because you don't know how to start and need to do research and read/watch some tutorials and try to mimic those layouts without knowing if you're doing the correct things. The good point on that is as there is no standard, "all" you do will be okay (however it's dangerous sometimes).&lt;/p&gt;

&lt;h2&gt;
  
  
  First approach
&lt;/h2&gt;

&lt;p&gt;When I started I tried to check a lot of repos on GitHub using the tag #Go and see how people are organizing their projects. Checking smaller ones or checking the big players in the industry like Docker, Kubernetes, AWS, ... My first approach was to use the still popular double folder:&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="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;pkg&lt;/span&gt;
&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Makefile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This was the initial approach that some Go projects were adopting where inside the &lt;code&gt;pkg&lt;/code&gt; you define all your code and in the &lt;code&gt;cmd&lt;/code&gt; you simply create your &lt;code&gt;main.go&lt;/code&gt; which bootstraps your application from the &lt;code&gt;pkg&lt;/code&gt; one. This started to be so popular because some Go examples from the Go Team were used. Some months/years later some people started to question if the &lt;code&gt;pkg&lt;/code&gt; folder was simply that, a folder, and it was not contributing anything to the project so it should be removed. For that time I was a clear defender of the &lt;code&gt;cmd, pkg&lt;/code&gt; layout because it was a "standard" for the industry and for me it was clear where to look at the code (pkg) and where to look at the initialization of the application  (cmd). This is still true, but advocating the simplicity of Go we tend to remove the packages that are just folders and give them also a meaningful name as they are part of our code (importing them and using in types, functions, etc.).&lt;/p&gt;

&lt;h2&gt;
  
  
  Ahá moment
&lt;/h2&gt;

&lt;p&gt;Some years ago I started reading about DDD due to the popularity it has acquired in the last years and I wanted to know what that about. I don't want to be extenze on this post about that topic (if you would like that I write one specific for it please ping me here or through my social networks and I will be happy to do it) but basically what it aims for is to put your focus when designing in the domain instead of in the code. It helps you to better understand the problem by giving you a toolkit to work with the domain experts in your company in order to design the best possible solution for the problem you wanna solve. There are two main groups, the strategic patterns and the tactical patterns. Both are important but here as I want to talk about the project layout I will talk only about the tactical ones. When I read those I started to internalise that all the domain design that I was doing with the strategical patterns, all the questions that I was asking to the domain experts, the ubiquitous language we were defining and all the event storming sessions we were doing, all of that should be reflected in my code. How can I do that? There are a lot of possibilities but one possibility is using Clean Architectures.&lt;br&gt;
At that moment it was when I read Robert C. Martin's book &lt;code&gt;Clean Architecture: A Craftsman's Guide to Software Structure and Design: A Craftsman's Guide to Software Structure and Design&lt;/code&gt;. Understanding what DDD aims for and the ideas conveyed in the book and after some refinement with my team colleagues we ended up creating a project layout in which we tried to gather all those concepts and the most important which we are comfortable working with. This is not to follow a trend or an imposition from any framework, so if we are not happy with it, we iterate it again and we tweak the parts we consider in order to facilitate our lives and specially our future selves when we need to do some fixes or add new features. &lt;/p&gt;
&lt;h2&gt;
  
  
  The layout
&lt;/h2&gt;

&lt;p&gt;Taking in consideration all I mentioned before, let me present to you the project layout. As an example I will use an application that has outgoing and incoming payments. Both with their own aggregates and business rules that need to satisfy and expose endpoints via grpc in this case.&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="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;payments&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;svc&lt;/span&gt;
&lt;span class="o"&gt;|-&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="o"&gt;|-&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="o"&gt;|-&lt;/span&gt; &lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="o"&gt;|-&lt;/span&gt; &lt;span class="n"&gt;grpc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="o"&gt;|-&lt;/span&gt; &lt;span class="n"&gt;incoming&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="o"&gt;|-&lt;/span&gt; &lt;span class="n"&gt;internal&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
    &lt;span class="o"&gt;|-&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
    &lt;span class="o"&gt;|-&lt;/span&gt; &lt;span class="n"&gt;postgres&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
    &lt;span class="o"&gt;|-&lt;/span&gt; &lt;span class="n"&gt;slack&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="o"&gt;|-&lt;/span&gt; &lt;span class="n"&gt;k8s&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="o"&gt;|-&lt;/span&gt; &lt;span class="n"&gt;outgoing&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;compose&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;yml&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="k"&gt;go&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;
&lt;span class="n"&gt;Makefile&lt;/span&gt;
&lt;span class="n"&gt;README&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;md&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I will try to be brief and explain a bit what parts each folder contains and why we adopted that layout.&lt;/p&gt;

&lt;p&gt;As I said this service is responsible for payments so we want to have the domain first exposed so we display &lt;code&gt;incoming&lt;/code&gt; and &lt;code&gt;outgoing&lt;/code&gt; as the main parts of the application. I will go back after a few lines, don't worry.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;app&lt;/code&gt; is where we have the &lt;code&gt;main.go&lt;/code&gt; to bootstrap all the applications (basically where we import the incoming and outgoing packages and some from the internal if needed).&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;cmd&lt;/code&gt; is where we define the command line tools we need for the service. In this case we have a cli that interacts with our service.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;docs&lt;/code&gt; is where we put the relevant documentation for this project.&lt;/p&gt;

&lt;p&gt;As I mentioned before the endpoints are exposed via &lt;code&gt;grpc&lt;/code&gt; so that folder is responsible for implementing the interfaces provided by the &lt;a href="https://developers.google.com/protocol-buffers" rel="noopener noreferrer"&gt;protobuffer&lt;/a&gt; compilation.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;internal&lt;/code&gt; is where we have the implementation of the interfaces we use in the project but are not part of the domain; basically the infrastructure things like the database, queues, external services (Slack), the logger...&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;k8s&lt;/code&gt; one is referred to the Kubernetes config files for the deployment.&lt;/p&gt;

&lt;p&gt;As mentioned before the &lt;code&gt;incoming&lt;/code&gt; and &lt;code&gt;outgoing&lt;/code&gt; are our domain packages so that is where all the magic happens. I will describe a bit of one of them because the other is similar but with the particularities of that domain.&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="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;outgoing&lt;/span&gt;
&lt;span class="n"&gt;app_service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="n"&gt;app_service_test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="n"&gt;display_payments&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="n"&gt;display_payments_test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="n"&gt;execute_payments&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="n"&gt;execute_payments_test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="n"&gt;flow_service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="n"&gt;flow_service_test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="n"&gt;instruction_repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="n"&gt;instruction_repository_test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="n"&gt;instruction&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="n"&gt;instruction_test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I've picked up the &lt;code&gt;outgoing&lt;/code&gt; for the explanation. First of all we have the &lt;code&gt;app_service&lt;/code&gt;. This is where we define the type Application Service of our package so what it means is that it will have all the dependencies for the package and one method for each Use Case. Note: the dependencies are interfaces. The &lt;code&gt;app_service_test&lt;/code&gt; is basically where we mock all the interfaces required for the app_service so we can reuse them in all the&lt;code&gt;*_test.go&lt;/code&gt; files.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;display_payments&lt;/code&gt; and &lt;code&gt;execute_payments&lt;/code&gt; are use cases for this domain. The tests are simply testing the different scenarios for each use case.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;flow_service&lt;/code&gt; is a domain service that helps us to execute the payments depending on the flow defined for each payment type. The test is basically testing the domain service.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;instruction_repository&lt;/code&gt; is where we define all the methods against our repository, in this case our database in PostgreSQL. The test is checking against a testing database if all the queries are okay.&lt;/p&gt;

&lt;p&gt;Last but not least, actually the most important is the aggregate &lt;code&gt;instruction&lt;/code&gt;. Inside that file is where we put everything important for this package. The aggregate is in charge of enforcing the business rules so that all the validations, checks, calculations, conversions, etc. needs to be here. (It's true that depending on the conversion or manipulation of the data or complex operations, it's better to have factories or other helpers, but I don't want to overcomplicate this example).&lt;/p&gt;

&lt;h2&gt;
  
  
  Application flow
&lt;/h2&gt;

&lt;p&gt;To finalize this long post let me describe how the flow of our app works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;app&lt;/code&gt; is the responsible of starting up the service&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;grpc&lt;/code&gt; will be the one receiving the request and answers the results&lt;/li&gt;
&lt;li&gt;once the request is mapped into our internal types by &lt;code&gt;grpc&lt;/code&gt; it will call the &lt;code&gt;app_service&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;inside the &lt;code&gt;app_service&lt;/code&gt; the corresponding &lt;code&gt;use case&lt;/code&gt; will be called&lt;/li&gt;
&lt;li&gt;depending on the &lt;code&gt;use case&lt;/code&gt; some &lt;code&gt;domain service&lt;/code&gt; should be called, some &lt;code&gt;repository&lt;/code&gt; will be called, or both, or more than 2... It depends!&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;I hope everything that I have tried to explain in this post has been clear, which was a lot, and please if there is any part that has not been completely clear or there are parts that I have not covered that you would like me to do, leave me a comment right here or through my social networks that you have on my profile and I will be happy to respond.&lt;/p&gt;

</description>
      <category>go</category>
      <category>ddd</category>
      <category>architecture</category>
      <category>cleancode</category>
    </item>
  </channel>
</rss>
